分类: C/C++
2008-05-31 10:42:37
BOOL CADOTest1App::InitInstance() { AfxOleInit(); ...... } |
#import \"c:\\program files\\common files\\system\\ado\\msado15.dll\" no_namespace rename(\"EOF\",\"adoEOF\") |
BOOL CADOTest1Dlg::OnInitDialog() { CDialog::OnInitDialog(); HRESULT hr; try { hr = m_pConnection.CreateInstance(\"ADODB.Connection\");///创建Connection对象 if(SUCCEEDED(hr)) { hr = m_pConnection->Open(\"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=test.mdb\",\"\",\"\",adModeUnknown);///连接数据库 //上面一句中连接字串中的Provider是针对ACCESS2000环境的,对于ACCESS97, //需要改为:Provider=Microsoft.Jet.OLEDB.3.51; } } catch(_com_error e)///捕捉异常 { CString errormessage; errormessage.Format(\"连接数据库失败!\\r\\n错误信息:%s\",e.ErrorMessage()); AfxMessageBox(errormessage);///显示错误信息 } |
HRESULT Connection15::Open ( _bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password, long Options ); |
上述函数中参数ConnectionString为连接字串;参数UserID是用户名;参数Password是登陆密码;参数Options是连接选项,用于指定Connection对象对数据的更新许可权,一般情况下Options可以是如下几个常量:
adModeUnknown:缺省。当前的许可权未设置
adModeRead:只读
adModeWrite:只写
adModeReadWrite:可以读写
adModeShareDenyRead:阻止其它Connection对象以读权限打开连接
adModeShareDenyWrite:阻止其它Connection对象以写权限打开连接
adModeShareExclusive:阻止其它Connection对象以读写权限打开连接
adModeShareDenyNone:阻止其它Connection对象以任何权限打开连接
我们给出一些常用的连接方式供大家参考:
m_pConnection->Open(\"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\\\\test.mdb\",\"\",\"\",adModeUnknown); |
m_pConnection->Open(\"Data Source=adotest;UID=sa;PWD=;\",\"\",\"\",adModeUnknown); |
m_pConnection->Open(\"driver={SQL Server};Server=127.0.0.1;DATABASE=vckbase; UID=sa;PWD=139\",\"\",\"\",adModeUnknown); |
m_pConnection->ConnectionTimeout = 5;///设置超时时间为5秒 m_pConnection->Open(\"Data Source=adotest;\",\"\",\"\",adModeUnknown); |
State属性指明当前Connection对象的状态,0表示关闭,1表示已经打开,我们可以通过读取这个属性来作相应的处理,例如:
if(m_pConnection->State) m_pConnection->Close(); ///如果已经打开了连接则关闭它 |
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) |
_variant_t RecordsAffected; ///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday m_pConnection->Execute(\"CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)\",&RecordsAffected,adCmdText); ///往表格里面添加记录 m_pConnection->Execute(\"INSERT INTO users(ID,username,old,birthday) VALUES (1, \'Washington\',25,\'1970/1/1\')\",&RecordsAffected,adCmdText); ///将所有记录old字段的值加一 m_pConnection->Execute(\"UPDATE users SET old = old+1\",&RecordsAffected,adCmdText); ///执行SQL统计命令得到包含记录条数的记录集 m_pRecordset = m_pConnection->Execute(\"SELECT COUNT(*) FROM users\",&RecordsAffected,adCmdText); _variant_t vIndex = (long)0; _variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量 m_pRecordset->Close();///关闭记录集 CString message; message.Format(\"共有%d条记录\",vCount.lVal); AfxMessageBox(message);///显示当前记录条数 |
_CommandPtr m_pCommand; m_pCommand.CreateInstance(\"ADODB.Command\"); _variant_t vNULL; vNULL.vt = VT_ERROR; vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数 m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它 m_pCommand->CommandText = \"SELECT * FROM users\";///命令字串 m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText); //执行命令取得记录集 |
m_pRecordset->Open(\"SELECT * FROM users\",_variant_t((IDispatch *)m_pConnection,true), adOpenStatic,adLockOptimistic,adCmdText); |
HRESULT Recordset15::Open ( const _variant_t & Source, const _variant_t & ActiveConnection, enum CursorTypeEnum CursorType, enum LockTypeEnum LockType, long Options ) |
enum CursorTypeEnum { adOpenUnspecified = -1,///不作特别指定 adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用 adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。 adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。 adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。 }; |
enum LockTypeEnum { adLockUnspecified = -1,///未指定 adLockReadOnly = 1,///只读记录集 adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制 adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作 adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。 }; |
参数Options的含义请参考本文中对Connection对象的Execute()方法的介绍。
5、记录集的遍历、更新
根据我们刚才通过执行SQL命令建立好的users表,它包含四个字段:ID,username,old,birthday
以下的代码实现:打开记录集,遍历所有记录,删除第一条记录,添加三条记录,移动光标到第二条记录,更改其年龄数据,保存到数据库。
_variant_t vUsername,vBirthday,vID,vOld; _RecordsetPtr m_pRecordset; m_pRecordset.CreateInstance(\"ADODB.Recordset\"); m_pRecordset->Open(\"SELECT * FROM users\",_variant_t((IDispatch*)m_pConnection,true), adOpenStatic,adLockOptimistic,adCmdText); while(!m_pRecordset->adoEOF) ///这里为什么是adoEOF而不是EOF呢?还记得rename(\"EOF\",\"adoEOF\")这一句吗? { vID = m_pRecordset->GetCollect(_variant_t((long)0));///取得第1列的值,从0开始计数,你也可以直接给出列的名称; vUsername = m_pRecordset->GetCollect(\"username\");///取得username字段的值 vOld = m_pRecordset->GetCollect(\"old\"); vBirthday = m_pRecordset->GetCollect(\"birthday\"); ///在DEBUG方式下的OUTPUT窗口输出记录集中的记录 if(vID.vt != VT_NULL && vUsername.vt != VT_NULL && vOld.vt != VT_NULL && vBirthday.vt != VT_NULL) TRACE(\"id:%d,姓名:%s,年龄:%d,生日:%s\\r\\n\",vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday); m_pRecordset->MoveNext();///移到下一条记录 } m_pRecordset->MoveFirst();///移到首条记录 m_pRecordset->Delete(adAffectCurrent);///删除当前记录 ///添加三条新记录并赋值 for(int i=0;i<3;i++) { m_pRecordset->AddNew();///添加新记录 m_pRecordset->PutCollect(\"ID\",_variant_t((long)(i+10))); m_pRecordset->PutCollect(\"username\",_variant_t(\"叶利钦\")); m_pRecordset->PutCollect(\"old\",_variant_t((long)71)); m_pRecordset->PutCollect(\"birthday\",_variant_t(\"1930-3-15\")); } m_pRecordset->Move(1,_variant_t((long)adBookmarkFirst));///从第一条记录往下移动一条记录,即移动到第二条记录处 m_pRecordset->PutCollect(_variant_t(\"old\"),_variant_t((long)45));///修改其年龄 m_pRecordset->Update();///保存到库中 |
m_pRecordset->Close();///关闭记录集 m_pConnection->Close();///关闭连接 |