分类: 数据库开发技术
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(3)、如在基本表视中点击添加数据过程: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); };
//选择添加记录 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;i基本过程就是两个:m_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); }这是一个与数据库交互的过程。