标题 VC++下使用ADO编写数据库程序 |
类别 编程珠矶 |
日期 07年02月09日 |
长度 9298 Bytes [Copy to clipboard] |
VC
++下使用
ADO
编写数据库程序
准备: ( 1 )、引入 ADO 类 #import "c:\program files\common files\system\ado\msado15.dll" \ no_namespace \ rename ( "EOF" , "adoEOF" ) ( 2 )、初始化 COM 在 MFC 中可以用 AfxOleInit ();非 MFC 环境中用: CoInitialize ( NULL ); CoUnInitialize (); ( 3 ) #import 包含后就可以用3个智能指针了:_ConnectionPtr、_RecordsetPtr和_CommandPtr 1 .连接和关闭数据库 ( 1 )连接 一般在 App 类成员函数 InitInstance ()里初始化 例子:连接 Access 数据库 AfxOleInit (); //初始化 HRESULT hr ; try { hr = m_pConnection . CreateInstance ( "ADODB.Connection" ); ///创建Connection对象 if ( SUCCEEDED ( hr )) { m_pConnection -> ConnectionTimeout = 0 ; hr = m_pConnection -> Open ( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db.mdb" , "" , "" , adModeUnknown ); //m_pConnection->PutDefaultDatabase ((_bstr_t)"DB");//设置默认数 据库 m_pCommand . CreateInstance ( __uuidof ( Command )); m_pCommand -> CommandTimeout = 5 ; m_pCommand -> ActiveConnection = m_pConnection ; } } catch ( _com_error e ) ///捕捉异常 { CString errormessage ; errormessage . Format ( "连接数据库失败!\r\n错误信息:%s" , e . ErrorMessage ()); AfxMessageBox ( errormessage ); ///显示错误信息 return FALSE ; } ( 2 )、关闭 一般在 App 类成员函数 InitInstance ()里关闭数据库连接 //如果数据库连接有效 if ( m_pConnection -> State ) m_pConnection -> Close (); m_pConnection = NULL ; ( 3 )、设置连接时间 //设置连接时间----------------------------------- pConnection -> put_ConnectionTimeout ( long ( 5 )); 2 .打开一个结果集 ( 1 )打开,首先创建一个 _RecordsetPtr 实例,然后调用 Open ()得到一条 SQL 语句的执行结果 _RecordsetPtr m_pRecordset ; m_pRecordset . CreateInstance ( __uuidof ( Recordset )); // 在ADO操作中建议语句中要常用try...catch()来捕获错误信息, // 因为它有时会经常出现一些意想不到的错误。jingzhou xu try { m_pRecordset -> Open ( "SELECT * FROM DemoTable" , // 查询DemoTable表中所有字段 m_pConnection . GetInterfacePtr (), // 获取库接库的IDispatch指针 adOpenDynamic , adLockOptimistic , adCmdText ); } catch ( _com_error * e ) { AfxMessageBox ( e -> ErrorMessage ()); } ( 2 )关闭结果集 m_pRecordset -> Close (); m_pRecordset = NULL ; 3 .操作一个结果集 ( 1 )、遍历(读取) a )、用 pRecordset -> adoEOF 来判断数据库指针是否已经移到结果集的末尾了; m_pRecordset -> BOF 判断是否 在第一 条记录前面: while (! m_pRecordset -> adoEOF ) { var = m_pRecordset -> GetCollect ( "Name" ); if ( var . vt != VT_NULL ) strName = ( LPCSTR ) _bstr_t ( var ); var = m_pRecordset -> GetCollect ( "Age" ); if ( var . vt != VT_NULL ) strAge = ( LPCSTR ) _bstr_t ( var ); m_AccessList . AddString ( strName + " --> " + strAge ); m_pRecordset -> MoveNext (); } b )、取得一个字段的值的办法有两种办法 一是 //表示取得第0个字段的值 m_pRecordset->GetCollect("Name"); 或者 m_pRecordset -> GetCollect ( _variant_t ( long ( 0 )); 二是 pRecordset -> get_Collect ( "COLUMN_NAME" ); 或者 pRecordset -> get_Collect ( long ( index )); ( 2 )、添加 a )、调用 m_pRecordset -> AddNew (); b )、调用 m_pRecordset -> PutCollect ( "Name" , _variant_t ( m_szName ));给每个字段赋值( m_szName 为控件所对应的字符串变量) c )、调用 m_pRecordset -> Update ();确认 // 添加完后可读取显示 对于 MFC 有些控件显示需要更新(比如 ListBox ) ( 3 )、修改 ( 4 )、删除 a )、把记录指针移动到要删除的记录上,然后调用 Delete ( adAffectCurrent ) try { // 假设删除第二条记录 m_pRecordset -> MoveFirst (); m_pRecordset -> Move ( 1 ); // 从0开始 m_pRecordset -> Delete ( adAffectCurrent ); // 参数adAffectCurrent为删除当前记录 m_pRecordset -> Update (); } catch ( _com_error * e ) { AfxMessageBox ( e -> ErrorMessage ()); } 4 .直接执行 SQL 语句,除了要用到结果集其余的大部分功能都可以直接用 SQL 语言实现 ( 1 )、用 _CommandPtr 和 _RecordsetPtr 配合 _CommandPtr m_pCommand ; m_pCommand . CreateInstance ( __uuidof ( Command )); // 将库连接赋于它 m_pCommand -> ActiveConnection = m_pConnection ; // SQL语句 m_pCommand -> CommandText = "SELECT * FROM DemoTable" ; // 执行SQL语句,返回记录集 m_pRecordset = m_pCommand -> Execute ( NULL , NULL , adCmdText ); ( 2 )、直接用 _ConnectionPtr 执行 SQL 语句 _RecordsetPtr Connection15 :: Execute ( _bstr_t CommandText , VARIANT * RecordsAffected , long Options ) 其中 CommandText 是命令字串,通常是 SQL 命令。 参数 RecordsAffected 是操作完成后所影响的行数, 参数 Options 表示 CommandText 中内容的类型, Options 可以取如下值之一: adCmdText :表明 CommandText 是文本命令 adCmdTable :表明 CommandText 是一个表名 adCmdProc :表明 CommandText 是一个存储过程 adCmdUnknown :未知 例子: _variant_t RecordsAffected ; m_pConnection -> Execute ( "UPDATE users SET old = old+1" ,& RecordsAffected , adCmdText ); 5 .调用存储过程 ( 1 )、利用 _CommandPtr _CommandPtr m_pCommand ; m_pCommand . CreateInstance ( __uuidof ( Command )); m_pCommand -> ActiveConnection = m_pConnection ; // 将库连接赋于它 m_pCommand -> CommandText = "Demo" ; m_pCommand -> Execute ( NULL , NULL , adCmdStoredProc ); ( 2 )、直接用 _ConnectionPtr 直接调用(见 4 .( 2 )) 6 .遍历数据库中的所有表名 _ConnectionPtr m_pConnect ; _RecordsetPtr pSet ; HRESULT hr ; try { hr = m_pConnect . CreateInstance ( "ADODB.Connection" ); if ( SUCCEEDED ( hr )) { CString dd ; dd . Format ( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s" , file ); hr = m_pConnect -> Open (( _bstr_t ) dd , "" , "" , adModeUnknown ); pSet = m_pConnect -> OpenSchema ( adSchemaTables ); while (!( pSet -> adoEOF )) { //获取表格 _bstr_t table_name = pSet -> Fields -> GetItem ( "TABLE_NAME" )- > Value ; //获取表格类型 _bstr_t table_type = pSet -> Fields -> GetItem ( "TABLE_TYPE" )- > Value ; //过滤一下,只输出表格名称,其他的省略 if ( strcmp ((( LPCSTR ) table_type ), "TABLE" )== 0 ){ CString tt ; tt . Format ( "%s" ,( LPCSTR ) table_name ); AfxMessageBox ( tt ); } pSet -> MoveNext (); } pSet -> Close (); } m_pConnect -> Close (); } catch ( _com_error e ) ///捕捉异常 { CString errormessage ; errormessage . Format ( "连接数据库失败!rn错误信息:%s" , e . ErrorMessage ()); AfxMessageBox ( errormessage ); return - 1 ; } 7 .遍历一个表中的所有字段 Field * field = NULL ; HRESULT hr ; Fields * fields = NULL ; hr = m_pRecordset -> get_Fields (& fields ); //得到记录集的字段集和 if ( SUCCEEDED ( hr )) fields -> get_Count (& ColCount ); //得到记录集的字段集合中的字段的总个数 for ( i = 0 ; iItem [ i ]-> get_Name (& bstrColName ); //得到记录集//中的字段名 strColName = bstrColName ; nameField = strColName ; m_FieldsList . AddString ( nameField ); } if ( SUCCEEDED ( hr )) fields -> Release (); //释放指针 附: 1 、 _variant_t ( 1 )、一般传给这 3 个指针的值都不是 MFC 直接支持的数据类型,而要用 _variant_t 转换一下 _variant_t ( XX )可以把大多数类型的变量转换成适合的类型传入: ( 2 )、 _variant_t var ; _variant_t -> long : ( long ) var ; _variant_t -> CString : CString strValue = ( LPCSTR ) _bstr_t ( var ); CString -> _variant_t : _variant_t ( strSql ); 2 、 BSTR 宽字符串与 CString 相互转换 BSTR bstr ; CString strSql ; CString -> BSTR : bstr = strSql . AllocSysString (); BSTR -> CString : strSql = ( LPCSTR ) bstr ; 3 、 _bstr_t 与 CString 相互转换 _bstr_t bstr ; CString strSql ; CString -> _bstr_t : bstr = ( _bstr_t ) strSql ; _bstr_t -> CString : strSql = ( LPCSTR ) bstr ; 4 、关于时间 Access :表示时间的字符串 #2004-4-5# Sql :表示时间的字符串 '' 2004 - 4 - 5 '' DateField (时间字段) select * from my_table where DateField > #2004-4-10# try { m_pCommand -> CommandText = "INSERT INTO tTest(age) VALUES('23f2') " ; m_pRecordset = m_pCommand -> Execute ( NULL , NULL , adCmdText ); } catch ( _com_error e ) ///捕捉异常 { CString errormessage ; errormessage . Format ( "连接数据库失败!\r\n错误信息:%s" , e . ErrorMessage ()); AfxMessageBox ( errormessage ); ///显示错误信息 } |
CopyRight By CoolDiyer All Rights Reserved
|