ado,全称 Activex Data Objects,他是微软公司为数据库应用程序开发的com集合。ado模型简单易学,功能强大,数据快。ado中包含7个核心对象,和4个集合:
对象:Connection,Command,Recordset,Field,Parameter,Error,Property
集合:parameters,fields,properties,errors
在本文中我们不对ado本身做太多的描述,只讲解其在vc++中的使用技巧。如果您对ado还很陌生,建议先阅读相关书籍。
如果想使用ADO,需要在要使用ADO的c++程序的头文件(*.h)中加入如下代码,引入ado对象:
#import c:programe filescommon filessystemadomsado15.dll no_namespace rename(
"
EOF,
"
ADOEOF
"
) rename(
"
BOF
"
,
"
ADOBOF
"
)
默认情况下msado15 位于c:/program files/common files/system/ado/ 。 我们一般都是按照上面的写法书写,当然也可以指定一个名称空间,或者将EOF 和 BOF 更名为其他什么的,都可以。
如果想使用ADO,还需要对OLE/COM库进行初始化。
::CoInitialize ( NULL ) ;
定义并实例化一个connection对象的方法如下:注意虽然conn是一个指针,但是依然不用->,因为CreateInstance是指针的方法。
_ConnectionPtr conn;
conn.CreateInstance(
"
adodb.connection
"
);
打开一个数据库连接的方法如下,以access数据库为例。
_bstr_t connsql
=
"
provider=microsoft.jet.oledb.4.0;data source=northsnow.mdb
"
;
conn
->
Open(connsql,
""
,
""
,adModeUnknown);
定义一个记录及对象,初始化,打开一个记录集的方法如下:
_RecordsetPtr rs;
rs.CreateInstance(
"
adodb.recordset
"
);
rs
->
Open(
"
select * from t order by a
"
,conn.GetInterfacePtr(),adOpenStatic,adLockReadOnly,adCmdText);
利用conn对象直接执行sql语句的方法如下:
_variant_t dC;
_bstr_t sql
=
"
delete from t where a=
"
+
m_l.GetItemText(nSelected,NULL);
conn
->
Execute(sql,
&
dC,adCmdText);
if
(dC.lVal
>=
0
)
...
{
//删除成功;
}
由于ado会经常出现莫名其妙的错误,所以需要用try/catch捕捉错误。
一个相对较完整的代码如下:
//
初始化ado
bool
CAdo1Dlg::initAdo()
...
{
if(conn==NULL)
...{
::CoInitialize(NULL);
HRESULT hr;
hr=conn.CreateInstance("adodb.connection");
try
...{
hr=conn.CreateInstance("adodb.connection");
if(SUCCEEDED(hr))
...{
conn->Open("provider=microsoft.jet.oledb.4.0;data source=db.mdb","","",adModeUnknown);
}
return 1;
}
catch(_com_error e)
...{
CString strError;
strError.Format("error:%s",e.Description());
AfxMessageBox(strError);
return 0;
}
}
else
...{
return 1;
}
}
//
添加listcontrol列头
m_l.SetExtendedStyle(LVS_EX_GRIDLINES
|
LVS_EX_FULLROWSELECT);
m_l.InsertColumn(
0
,
"
code
"
,LVCFMT_RIGHT,
50
);
m_l.InsertColumn(
1
,
"
name
"
,LVCFMT_LEFT,
100
);
m_l.InsertColumn(
2
,
"
age
"
,LVCFMT_RIGHT,
50
);
m_l.InsertColumn(
3
,
"
birth
"
,LVCFMT_RIGHT,
200
);
//
向listcontrol添加内容:
void
CAdo1Dlg::LoadData()
...
{
m_l.DeleteAllItems();
if(initAdo()==1)
...{
_RecordsetPtr rs;
HRESULT hr;
int i=0;
try
...{
rs.CreateInstance("adodb.recordset");
rs->Open("select * from t order by a",conn.GetInterfacePtr(),adOpenStatic,adLockReadOnly,adCmdText);
while(!rs->ADOEOF)
...{
m_l.InsertItem(i,(LPCTSTR)(_bstr_t)rs->GetCollect("a"));
m_l.SetItemText(i,1,(LPCTSTR)(_bstr_t)rs->GetCollect("b"));
m_l.SetItemText(i,2,(LPCTSTR)(_bstr_t)rs->GetCollect("c"));
m_l.SetItemText(i,3,(LPCTSTR)(_bstr_t)rs->GetCollect("d"));
i++;
rs->MoveNext();
}
}
catch(_com_error e)
...{
AfxMessageBox(e.Description());
}
}
}
//
向数据库添加信息
UpdateData(
true
);
if
(m_b.GetLength()
==
0
)
...
{
AfxMessageBox("a项不能为空!",NULL,NULL);
}
CString strD
=
m_d.Format(
"
%Y-%m-%d %H:%M:%S
"
);
_bstr_t sql
=
"
insert into t(b,c,d) values('
"
+
m_b
+
"
',
"
+
CStr(m_c)
+
"
,'
"
+
strD
+
"
')
"
;
AfxMessageBox(sql);
try
...
{
if(initAdo()==1)
...{
conn->Execute(sql,NULL,adCmdText);
}
}
catch
(_com_error e)
...
{
CString strError;
strError.Format("error:%s",e.Description());
AfxMessageBox(strError,NULL,NULL);
}
//
删除一条信息
if
(MessageBox(
"
do you really want to delete the infomation?
"
,
"
prompt
"
,
1
)
==
IDOK)
...
{
int nSelected=-1;
nSelected=m_l.GetNextItem(nSelected,LVNI_SELECTED);
if(nSelected>=0)
...{
if(initAdo()==1)
...{
_variant_t dC;
_bstr_t sql="delete from t where a=" + m_l.GetItemText(nSelected,NULL);
try
...{
conn->Execute(sql,&dC,adCmdText);
if(dC.lVal>=0)
...{
LoadData();
}
}
catch(_com_error e)
...{
AfxMessageBox(e.Description());
}
}
}
}
//
两个类型转换的程序:
CString CAdo1Dlg::CStr(
long
s)
...
{
CString mm;
mm.Format("%d",s);
return mm;
}
CString CAdo1Dlg::DblToStr(
double
s)
...
{
CString mm;
mm.Format("%f",s);
return mm;
}
上面的程序中只包含了核心的代码。没有包含一些界面设置,变量的定义等细节信息。所以请借用代码的时候注意一下。
代码中还有几项需要注意:
1,catch 捕捉的错误的类型为 _com_error,其产生的错误描述信息为: e.Description()
2,listcontrol中获得当前选择行的方法为:
int
nSelected
=-
1
;
nSelected
=
m_l.GetNextItem(nSelected,LVNI_SELECTED);
3,listcontrol中获得当前选择行的某个itemtext的方法为:
m_l.GetItemText ( nSelected,NULL )
//
其中第二个参数表示是第几个subitem。如果为NULL,则表示为Item
当关闭记录集的时候为如下代码:
if
(rs
!=
NULL)
rs
->
Close();
if
(conn
!=
NULL)
conn
->
Close();
::CoUninitialize ();
基本上就是这些。