分类: 数据库开发技术
2008-03-14 10:35:22



![]() |
![]() |
| 图四 添加记录 | 图五 添加记录 |
图四中的年级编号在年级表中索引得到;图五中的班级编号在班级表中索引得到,课程编号在课程表中索引得到,该怎么做?
(1)、数据库结构方面:参考了用友数据库的一些表的设计,然后就想把数据表<表说明>中增加了字段:外键个数,字段0,外键0,外部表0,显示字段0…..字段n:(现在数据库预设计为一个表可以最多有4个外键)。
(2)、程序类方面:设计了一个记录字段信息(CFieldRecord)以及一个基本表类(CBaseTbl):
//记录信息量
struct CFieldRecord
{
char FieldName[20];//字段名(如果为外键字段,则为显示字段)
char Value[255]; //值
bool IsBool; //是否布尔
bool IsStrType; //是否字符串
bool IsVisible; //是否显示
char DisplayName[20]; //对应ID值(用于外键)
char FKtbl[20]; //外键表名或基本表名
CFieldRecord* pFK; //外键信息
};
//基本表的处理
class CBaseTbl : public CObject
{
public:
CBaseTbl();
virtual ~CBaseTbl();
CList m_TblList;//名称列表
void GetTblnames();
//单表记录数组,默认记录最后一条
bool GetFieldRecord(CPtrArray& FieldArray,CString ctblname,CString constr="");
bool RemoveRecord(int CurRecordPos);
protected:
CADOStorage m_Storage;
//单表记录数组,默认记录最后一条
void AddExtraFieldRecord(CPtrArray& FieldArray,CString ctblname);
private:
CString m_TblName;
public:
//选择联合表
bool SelectUnionTbl(CString StrTblname,CString& Realtbl,bool ByRealTblName=false);
void RefreshList(CListCtrl& List1);
void ReQuery(CString TblName);
void ExecSql(CString SqlStr);
};
(3)、如在基本表视中点击添加数据过程://选择添加记录
void CStudentScoreView::OnADDRecord()
{
ASSERT(this->m_hWnd);
CBMDialog dialog1;
CStudentScoreDoc* pDoc=this->GetDocument();
pDoc->m_BaseTblList.GetFieldRecord(dialog1.RecordArray,this->m_CurTblName);
dialog1.ISADD=true;
dialog1.m_hParent=this->m_hWnd;
dialog1.m_OprTblName=this->m_CurTblName;
if(dialog1.DoModal()==IDOK)
{
AfxMessageBox("添加记录!");
//ASSERT(dialog1.m_hWnd);
}
} 申明为:文档类中 CBaseTbl m_BaseTblList;//表信息实例//单表记录数组
bool CBaseTbl::GetFieldRecord(CPtrArray& FieldArray,CString ctblname,CString constr)
{
ASSERT(ctblname.Trim()!="");
//1.判断及清理工作
…省略
CFieldRecord* fldrec;
CADOFieldInfo fldinfo;
CString fldvalue;
//2.判断记录位置
bool IsZeroRecord;//记录数为0
…省略
int count=this->m_Storage.GetFieldCount();
//3.添加字段记录到指针数组
for(int i=0;im_Storage.GetFieldValue(i,fldvalue);
}
this->m_Storage.GetFieldInfo(i,&fldinfo);
strcpy(fldrec->FKtbl,ctblname);
strcpy(fldrec->FieldName,fldinfo.m_strName);
strcpy(fldrec->Value,fldvalue);
switch(fldinfo.m_nType)
{
case VT_DATE:
fldrec->IsStrType=true;
fldrec->IsBool =false;
break;
…
default:
fldrec->IsStrType=false;
fldrec->IsBool =false;
break;
}
fldrec->pFK=NULL;
fldrec->IsVisible=true;
FieldArray.Add(fldrec);
}
//添加外键信息
this->AddExtraFieldRecord(FieldArray,ctblname);
return true;
} 基本过程就是两个: //动态创建组件
CFieldRecord* pRecord;
int top=0;
for(int i=1;i<=this->RecordArray.GetCount();i++)
{
top=(i-1)*22;
pRecord=(CFieldRecord*)RecordArray.GetAt(i-1);
this->CreateStatic(pRecord,top,70+i);
//布尔或有关联外键
if((pRecord->IsBool)||(pRecord->pFK!=NULL))
this->CreateCombo(pRecord,top,10+i);
else
this->CreateEdit(pRecord,top,10+i);
} 注:有关联外件就读取关联表显示字段的索引信息,然后添加到 ComboBox 中,//发送修改或添加消息
void CBMDialog::SendChangeMsg(void)
{
CWnd* pWnd;
CString value,Msg;
CFieldRecord* pRecord;
for(int i=1;i<=this->RecordArray.GetCount();i++)
{
pWnd=this->GetDlgItem(10+i);
if(pWnd)
{
pRecord=(CFieldRecord*)RecordArray.GetAt(i-1);
if ((!pRecord->IsBool)&&pWnd->IsKindOf(RUNTIME_CLASS(CComboBox)))
{ //非布尔类型,且有关联字段时
CComboBox* pCombo=(CComboBox*) pWnd;
CFldValue* p;
int index=pCombo->GetCurSel();
p=(CFldValue*)pCombo->GetItemDataPtr(index);
value=p->FieldValue;
}
else
pWnd->GetWindowText(value);
if(value.Trim()=="")
{
Msg=(CString)pRecord->FieldName+"不能为空!";
AfxMessageBox(Msg);
pWnd->SetFocus();
return;
}
else
{
if((i==1)&&(!this->ISADD))//如果是修改的话,则不对第一字段操作
{}
else
strcpy(pRecord->Value,value);
}
}
}
//发送字符串
CString cSend;
if(this->ISADD)
{
cSend=this->GenerateInsertSql();
}
else
{
cSend=this->GenerateUpdateSql();
}
LPARAM lparam=(LPARAM)&cSend;
::SendMessage((HWND)this->m_hParent,WM_USER+51,0,lparam);
}这是基本的信息,根据显示内容生成sql语句,发送消息给基本表视,完成数据库更新操作。LRESULT CStudentScoreView::OnExecSql(WPARAM wParam,LPARAM lParam)
{
CString c;
c=*((CString*)lParam);
CStudentScoreDoc* pDoc=this->GetDocument();
pDoc->m_BaseTblList.ExecSql(c);
this->RefreshShow();
//AfxMessageBox(c);
return 0;
} 2.关于考试过程的编码class CExam : public CObject
{
public:
CExam();
virtual ~CExam();
CString m_No; //考试编号
COleDateTime m_Date; //考试日期
CString m_TermNo; //学期编号
CStringList& GetTerms();
CStringList* GetNos();
protected:
CADOStorage m_Storage;//数据库连接
CString m_TblName; //表名称
private:
CStringList m_TermList;//学期列表
CStringList m_NoList; //编号列表
public:
void ClearTermList(void);
void ClearNoList(void);
void GetExamByNo(CString No);//获取考试信息
bool IsNoExisted(CString No);//编号是否存在
void AddExam();
void DeleteExamByNo(CString No);
};
(1)、在文档类中申明CExam m_Exam.添加记录 void CExamView::OnBnClickedButton2()
{
CEdit* pEdit=(CEdit*) this->GetDlgItem(IDC_EDIT1);
CString ExamNo;
pEdit->GetWindowText(ExamNo);
CExamDoc* pDoc=this->GetDocument();
if(pDoc->m_Exam.IsNoExisted(ExamNo))
{
AfxMessageBox("不能添加重复记录!");
return;
}
else
{
//添加记录
pDoc->m_Exam.m_No=ExamNo;
CDateTimeCtrl* pPicker=
(CDateTimeCtrl*)this->GetDlgItem(IDC_DATETIMEPICKER1);
pPicker->GetTime(pDoc->m_Exam.m_Date);
CComboBox* pComb=(CComboBox*)this->GetDlgItem(IDC_COMBO1);
pComb->GetLBText(pComb->GetCurSel(),pDoc->m_Exam.m_TermNo);
pDoc->m_Exam.AddExam();
}
} (2)、然后看: pDoc->m_Exam.AddExam(); void CExam::AddExam()
{
CString FldList,ValueList;
FldList="考试编号,考试日期,学期编号";
ValueList="''''"+this->m_No+"'''',''''"+this->m_Date.Format()+"'''',''''"+this->m_TermNo+"''''";
this->m_Storage.ExecInsertSql(this->m_TblName,FldList,ValueList);
} 这是一个与数据库交互的过程。