ODBC(怒放式数据库Databnse连接)是一种应用SQL的程式设计接口,应用ODBC使数据库Databnse实际运用程式的编写者避免了与数据源相连接的复杂性。利用ODBC技能使得程式员从具体的DBMS中解脱出来,从而能够递减热门软件开发的务工量,缩短开发周期,并升高效率和热门软件的可靠性。这项技能目前已经得到了大多数DBMS厂商的广泛支持。
Microsoft Developer Studio为大多数达标的数据库Databnse各式帮助了32位ODBC驱动器。这一部份达标数据各式包括有:SQL Server、Access、Paradox、dBase、FoxPro、Excel、Oracle数据库以及Microsoft Text。假如用户期望应用更多有联系数据各式,则需求安装相应的ODBC驱动器及DBMS。
用户应用自个的DBMS数据库Databnse管制功能生成新的数据库Databnse模式后,就能够应用ODBC来登录数据源。对用户的实际运用程式来说,只要安装有驱动程式,就能注册很多不相同的数据库Databnse。登录数据库Databnse的具体操作参见有关ODBC的联机帮助。
一、MFC帮助的ODBC数据库Databnse类
Visual C++的MFC基类库定义了几个数据库Databnse类。在利用ODBC编程时,经常要应用到 CDatabase(数据库Databnse类)、CRecordSet(记录集类)和CRecordView(可视记录集类)。
CDatabase类对象帮助了对数据源的连接,经过它能够对数据源停止操作。
CRecordSet类对象帮助了从数据源中提取出的记录集。CRecordSet对象通日常于两种形式:动态行集(dynasets)和快照集(snapshots)。动态行集能与更多有联系用户所做的更改保持同步,快照集则是数据的唯一静态视图。每种形式在记录集被打开时都帮助一组记录,所不相同的是,当在唯一动态行集里滚动到一条记录时,由更多有联系用户或实际运用程式中的更多有联系记录集对该记录所做的更改会相应地呈现出来。
CRecordView类对象能以控件的形式呈现数据库Databnse记录,那个视图是直接连到唯一CRecordSet对象的表视图。
二、实际运用ODBC编程
实际运用Visual C++的AppWizard能够自动生成唯一ODBC实际运用程式框架,步骤是:打开File菜单的New选项,选取Projects,填入工程名,选取MFC AppWizard (exe),然后按AppWizard的提示停止操作。
当AppWizard询问也许包含数据库Databnse支持时,假如想读写数据库Databnse,那么选定Database view with file support;假如想来访数据库Databnse的消息而不想写回所做的改变,那么选定Database view without file support。
选好数据库Databnse支持之后,Database Source 按钮会被激活,选中它去调用Data Options对话框。在Database Options对话框中会呈现出已向ODBC注册的数据库Databnse资源,选定所要操作的数据库Databnse,如:Super_ES,单击OK后呈现Select Database Tables对话框,其中列举了选中的数据库Databnse包含的全部表;选取要操作的表后,单击OK。在选定了数据库Databnse和数据表之后,就能够按照惯例继续停止AppWizard操作。
特别需求指出的是:在生成的实际运用程式框架View类(如:CSuper_ESView)中,包含唯一指向CSuper_ESSet对象的指针m_pSet,该指针由AppWizard建立,目的是在视表单和记录集之间建立联系,使得记录集中的查询结果能够很简易地在视表单上呈现出来。
要使程式与数据源建立联系,需用CDateBase::OpenEx()或CDatabase::Open()参数来停止初始化。数据库Databnse对象必需在应用它构造记录集对象之前初始化。
#p#
三、举例
1.查询记录
查询记录应用CRecordSet::Open()和CRecordSet::Requery()成员参数。在应用CRecordSet类对象之前,必需应用CRecordSet::Open()参数来获得有效的记录集。一旦已经应用过CRecordSet::Open()参数,再次查询时就能够实际运用CRecordSet::Requery()参数。
在调用CRecordSet::Open()参数时,假如将唯一已经打开的CDatabase对象指针传给CRecordSet类对象的m_pDatabase成员变量,则应用该数据库Databnse对象建立ODBC连接;否则假如m_pDatabase为空指针,就新建唯一CDatabase类对象,并使其与缺省的数据源相连,然后停止CRecordSet类对象的初始化。缺省数据源由GetDefaultConnect()参数获得。也能够帮助所需求的SQL语句,并以它来调用CRecordSet::Open()参数,
例如:
- Super_ESSet.Open(AFX_DATABASE_USE_DEFAULT,strSQL);
假如没有指定参数parameter,程式则应用缺省的SQL语句,即对在GetDefaultSQL()参数中指定的SQL语句停止操作:
- CString CSuper_ESSet::GetDefaultSQL()
- {return _T(″[BsicData],[MinSize]″);}
对于GetDefaultSQL()参数返回的表名,对应的缺省操作是SELECT语句,即:
- SELECT * FROM BasicData,MainSize
在查询过程中,也能够利用CRecordSet的成员变量m_strFilter和m_strSort来执行要求查询和结果排序。m_strFilter为滤掉字符串,存放着SQL语句中WHERE后的要求串;m_strSort为排序字符串,存放着SQL语句中ORDER BY后的字符串。如:
- Super_ESSet.m_strFilter=″TYPE=‘电动机’″;
- Super_ESSet.m_strSort=″VOLTAGE″;
- Super_ESSet.Requery();
对应的SQL语句为:
- SELECT * FROM BasicData,MainSize
- WHERE TYPE=‘电动机’
- ORDER BY VOLTAGE
除了直接赋值给m_strFilter以外,还能够应用参数parameter化。利用参数parameter化能够更直观、更方便地完成要求查询任务。应用参数parameter化的步骤如下:
S声明参变量:
- CString p1;
- float p2;
S在构造参数中初始化参变量:
- p1=_T(″″);
- p2=0.0f;
- m_nParams=2;
S将参变量与对应列绑定:
- pFX->SetFieldType(CFieldExchange::param)
- RFX_Text(pFX,_T(″P1″),p1);
- RFX_Single(pFX,_T(″P2″),p2);
完成以上步骤后就能够利用参变量停止要求查询:
- m_pSet->m_strFilter=″TYPE=? AND VOLTAGE=?″;m_pSet->p1=″电动机″;
- m_pSet->p2=60.0;
- m_pSet->Requery();
参变量的值按绑定的顺序替换查询字串中的“?”通配符。
假如查询的结果是多条记录,能够用CRecordSet类的参数Move()、MoveNext()、MovePrev()、MoveFirst()和MoveLast()来移动光标。
2.渐增记录
渐增记录应用AddNew()参数,要求数据库Databnse必需是以允许渐增的方法打开:
- m_pSet->AddNew(); //在表的末尾渐增新记录
- m_pSet->SetFieldNull(&(m_pSet->m_type), FALSE);
- m_pSet->m_type=″电动机″;
- ……
- //输入新的字段值
- m_pSet->Update();
- //将新记录存入数据库Databnse
- m_pSet->Requery();
- //重建记录集
3.删除记录
能够直接应用Delete()参数来删除记录,并且在调用Delete()参数之后不需调用Update()参数:
- m_pSet->Delete();
- if (!m_pSet->IsEOF())
- m_pSet->MoveNext();
- else
- m_pSet->MoveLast();
4.改正记录
改正记录应用Edit()参数:
- m_pSet->Edit();
- //改正当前记录
- m_pSet->m_type=″发电机″;
- //改正当前记录字段值
- ……
- m_pSet->Update(); //将改正结果存入数据库Databnse
- m_pSet->Requery();
5.撤消操作
假如用户选取了渐增或者改正记录后期望放弃当前操作,能够在调用Update()参数之前调用:
CRecordSet::Move(AFX_MOVE_REFRESH)来撤消渐增或改正模式,并恢复在渐增或改正模式之前的当前记录。其中,参数parameterAFX_MOVE_REFRESH的值为零。
6.数据库Databnse连接的复用
在CRecordSet类中定义了唯一成员变量m_pDatabase:
- CDatabase* m_pDatabase;
它是指向对象数据库Databnse类的指针。假如在CRecordSet类对象调用Open()参数之前,将唯一已经打开的CDatabase类对象指针传给m_pDatabase,就能共享相同的CDatabase类对象。如:
- CDatabase m_db;
- CRecordSet m_set1,m_set2;
- m_db.Open(_T(″Super_ES″)); //建立ODBC连接
- m_set1.m_pDatabase=&m_db;
- //m_set1复用m_db对象
- m_set2.m_pDatabse=&m_db;
- // m_set2复用m_db对象
7.SQL语句的直接执行
虽然咱们能够经过CRecordSet类完成大多数的查询操作,而且在CRecordSet::Open()参数中也能够帮助SQL语句,但是有时候咱们还那样期望停止一部份更多有联系操作,例如建立新表、删除表、建立新的字段等,这时就需求应用CDatabase类直接执行SQL语句的机制。经过调用CDatabase::ExecuteSQL()参数来完成SQL语句的直接执行:
- BOOL CDB::ExecuteSQLAndReportFailure(const CString& strSQL)
- {TRY
- {m_pdb->ExecuteSQL(strSQL);
- //直接执行SQL语句}
- CATCH (CDBException,e)
- {CString strMsg;
- strMsg.LoadString(IDS_EXECUTE_SQL_FAILED);
- strMsg+=strSQL;
- return FALSE;}
- END_CATCH
- return TRUE;}
应当指出的是,由于不相同的DBMS帮助的数据操作语句不尽相同,直接执行SQL语句估计会破坏热门软件的DBMS无关性,因此在实际运用中应当慎用此类操作。
8.动态连接表
表的动态连接能够利用在调用CRecordSet::Open()参数时指定SQL语句来呈现。同唯一记录集对象只能来访具有相同框架的表,否则查询结果将无法与变量相对应。
- void CDB::ChangeTable()
- {
- if (m_pSet->IsOpen()) m_pSet->Close();
- switch (m_id)
- {
- case 0:
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,
- ″SELECT * FROM SLOT0″);
- //连接表SLOT0
- m_id=1;
- break;
- case 1:
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,
- ″SELECT * FROM SLOT1″); //连接表SLOT1
- m_id=0;
- break; }}
9.动态连接数据库Databnse
能够经过赋与CRecordSet类对象参数parameterm_pDatabase来连接不相同数据库Databnse的CDatabase对象指针,从而呈现动态连接数据库Databnse。
- void CDB::ChangeConnect()
- {CDatabase* pdb=m_pSet->m_pDatabase;
- pdb->Close();
- switch (m_id)
- {
- case 0:
- if (!pdb->Open(_T(″Super_ES″)))
- //连接数据源Super_ES
- {
- AfxMessageBox(″数据源Super_ES打开失败″,″请检查相应的ODBC连接″, MB_OK|MB_ICONWARNING);
- exit(0);
- }
- m_id=1;
- break;
- case 1:
- if (!pdb->Open(_T(″Motor″)))
- //连接数据源Motor
- {
- AfxMessageBox(″数据源Motor打开失败″,″请检查相应的ODBC连接″, MB_OK|MB_ICONWARNING);
- exit(0);
- }
- m_id=0;
- break; }}
总结:Visual C++中的ODBC类库能够帮助程式员完成绝大多数的数据库Databnse操作。利用ODBC技能使得程式员从具体的DBMS中解脱出来,从而能够递减热门软件开发的务工量,缩短开发周期,并升高效率和热门软件的可靠性。希望本文能对你有帮助。