teardrop
对于数据库的操作使用,对于我们编程开发来说,是比较常见的事情,也是常用的技术。所以,应该要熟悉掌握。对于数据库的操作,基本操作就是增、删、改、查。但是,在进行这些基本操作之前,还有至关重要的一步,就是数据库的连接。对于数据库的成功连接,那么,我们对数据库的操作就完成一半了。很多初学者,都会卡死在数据库连接这一步上面。
本文介绍的是ADO方式连接数据库,并操作数据库。ADO(ActiveX Data Object)具有跨系统平台特性,它直接对DBMS数据库进行操作,即系统中必须有DBMS,但不需要驱动程序,不需要注册数据源,所以具有很好的可移植性。
本文就给出ADO方式连接并操作 SQL Server数据、Access数据库、Oracle数据库、MySQL数据库等常用数据库,虽然有很多数据库,但是它们之间对于ADO来说,只是连接字符串的区别而已。
现在,我就把程序实现的过程整理成文档,分享给大家。
在使用ADO技术时需要导入一个ADO动态链接库msado15.dll,该动态库位于系统盘下的”Program Files\Common Files\System\ado\”目录下。然后,我们在程序头文件中,添加下面的导入代码:
#import "C:\\Program Files\\common files\\system\\ado\\msado15.dll" no_namespace rename("EOF","adoEOF")
我们在操作数据库之前,首先要连接数据库。数据库连接至关重要一点就是,数据库连接字符串。现在,我们先来介绍下ADO连接数据库的一个流程:
首先,我们先调用 CoInitialize 初始化COM组件环境,因为ADO方式连接数据库,就是基于COM组件实现的。所以,必须要对COM环境进行初始化
然后,调用 _ConnectionPtr::CreateInstance 函数创建 Connection 对象
创建成功后,对 Connection 对象的连接超时ConnectionTimeout进行设置,同时调用 Open 函数,按照数据库连接字符串连接数据库
经过,这 3 步操作,就成功完成数据库连接的操作。我们上面说,不同数据库,连接字符串也会不同。下面,我就列举常用数据库的连接字符串:
Access连接字符串
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=MDB文件路径;Persist Security Info=False;Jet OLEDB:DataBase Password=数据库密码
数据源连接字符串
"DSN=TestDatabase;UID=;PWD=;"
SQL Server连接字符串
Driver=SQL Server;Server=服务器IP;Database=数据库名称;UID=用户名;PWD=密码
Oracle连接字符串
Provider=MSDAORA.1; Password=sa123; User ID=system; Data Source=192.168.0.221/orcl; Persist Security Info=True
MySQL连接字符串
Driver=MySQL ODBC 5.2 ANSI Driver;SERVER=192.168.0.221;UID=用户名;PWD=密码;DATABASE=test;PORT=端口(默认填写3306)
// 以ADO方式连接数据库
BOOL ADOConnectDatabase(_bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password)
{
// 初始化COM对象
::CoInitialize(NULL);
try
{
// 创建Connection对象
HRESULT hr = g_pConnection.CreateInstance("ADODB.Connection");
if (SUCCEEDED(hr))
{
// 连接超时时间 5 秒
g_pConnection->ConnectionTimeout = 5;
// 连接数据库
g_pConnection->Open(ConnectionString, UserID, Password, adModeUnknown);
return TRUE;
}
}
catch (_com_error e)
{
::MessageBox(NULL, e.Description(), e.ErrorMessage(), MB_OK);
}
return FALSE;
}
首先,我们调用 _ConnectionPtr::BeginTrans 函数,开始事务
然后,调用 _ConnectionPtr::Execute 函数执行SQL语句,这里可以提交多条SQL语句。在调用 Execute 函数的时候,数据库还没有执行SQL语句,此时SQL语句还没有生效
最后,我们调用 _ConnectionPtr::CommitTrans 函数提交事务,这时所提交的SQL语句开始按提交顺序执行。如果出错,则调用 _ConnectionPtr::RollbackTrans 函数回滚并结束事务
// 执行操作SQL语句
BOOL ExecuteSQL(char *pszSQL)
{
_variant_t ra;
// 开始事务
g_pConnection->BeginTrans();
try
{
// 执行SQL语句
g_pConnection->Execute((_bstr_t)pszSQL, &ra, adCmdText);
// 提交事务
g_pConnection->CommitTrans();
return TRUE;
}
catch (_com_error e)
{
::MessageBox(NULL, e.Description(), e.ErrorMessage(), MB_OK);
}
// 如果出现错误,回滚并结束事务
g_pConnection->RollbackTrans();
return FALSE;
}
查询SQL语句与其它操作的SQL语句不一样,它不是使用 _ConnectionPtr 对象进程操作的,而是使用记录集对象 _RecordsetPtr 来进行实现。
首先,我们调用 _RecordsetPtr::CreateInstance 函数创建并初始化记录集对象
然后,_RecordsetPtr::Open 函数打开记录集并执行查询SQL语句,将查询结果,返回到记录集中
// 执行查询SQL语句
BOOL SearchSQL(char *pszSQL)
{
// 初始化记录集对象
g_pRecordset.CreateInstance(_uuidof(Recordset));
// 打开记录集
g_pRecordset->Open((LPCTSTR)pszSQL, g_pConnection.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText);
if (NULL == g_pRecordset)
{
::MessageBox(NULL, "读取数据库记录出错", "ERROR", MB_OK);
return FALSE;
}
return TRUE;
}
我们在 main 函数中调用上述封装好的函数,连接数据库,执行创建demongan数据库表的SQL语句,执行向demongan表插入5条数据的SQL语句,执行查询demongan表所有数据并显示在程序上。main 函数为:
int _tmain(int argc, _TCHAR* argv[])
{
BOOL bRet = FALSE;
char szSQL[MAX_PATH] = {0};
// 连接数据库
bRet = ADOConnectDatabase("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb", "", "");
if (FALSE == bRet)
{
printf("Connect Database Error.\n");
}
printf("Connect Database OK.\n");
// 执行SQL语句,创建表 demongan
::wsprintf(szSQL, "CREATE TABLE demongan(ID int, Name varchar(20), Age int)");
bRet = ExecuteSQL(szSQL);
if (FALSE == bRet)
{
printf("Create Table Error.\n");
}
printf("Create Table OK.\n");
// 执行SQL语句,插入 5 条记录
for (int i = 0; i < 5; i++)
{
::wsprintf(szSQL,
"INSERT INTO demongan(ID, Name, Age) VALUES(%d, \'%s%d\', %d)",
i, "Name", i, i + 1);
bRet = ExecuteSQL(szSQL);
if (FALSE == bRet)
{
printf("Insert Value Error.\n");
}
}
printf("Insert Value OK.\n");
// 查询数据
::wsprintf(szSQL, "SELECT * FROM demongan");
bRet = SearchSQL(szSQL);
if (FALSE == bRet)
{
printf("Search Value Error.\n");
}
printf("Search Value OK.\n");
// 从记录集中获取数据并显示
_variant_t varID, varName, varAge;
while (!g_pRecordset->adoEOF)
{
// 获取每个字段对应的数据
varID = g_pRecordset->GetCollect("ID");
varName = g_pRecordset->GetCollect("Name");
varAge = g_pRecordset->GetCollect("Age");
// 注意要强制转换下显示类型
printf("%s\t%s\t%s\n", (LPCTSTR)_bstr_t(varID), (LPCTSTR)_bstr_t(varName), (LPCTSTR)_bstr_t(varAge));
// 获取下一行数据
g_pRecordset->MoveNext();
}
system("pause");
return 0;
}
我们直接运行程序,程序提示运行成功,成功连接数据库、创建表、插入数据、查询数据并显示查询结果:
我们打开数据库文件,直接查看,数据成功被插入:
数据库操作要注意 3 个关键点:
一是与数据库的连接,要注意连接字符串一定要写正确,不同类型的数据库,连接字符串也会不同
二是执行数据库的增加、删除、修改等除查询操作之外的SQL语句,先要开始事务,待所有SQL语句提交完毕后,再一次提交事务,交由数据库操作
三是执行数据库的查询语句,查询结果,需要从记录集中一条一条循环获取,要注意循环结束的条件
其中,在显示从数据集获取的数据的时候,我们要对数据进行(LPCTSTR)强制转化你,例如 (LPCTSTR)_bstr_t(varName),否则数据不能正常显示。
参考自《Windows黑客编程技术详解》一书
keyboard_arrow_left上一篇 : Linux下使用Qt批量创建动态链接库软链接 使用VS2013创建并操作SQLite数据库 : 下一篇keyboard_arrow_right