记录下ADO连接的详细步骤,方便以后忘记了回来查看。我用的环境:VS2017+Windows10+SQL Server。
1、引入ADO库:无需导入任何头文件,使用以下方法即可
// 说明:#import的这个路径,windows系统里面自带有ado的动态库。
//不同的操作系统可能msado15.dll这个库的名字不一样,这里以windows10为例,我这里是msado15.dll
#import "C:\Program Files\Common Files\System\ado\msado15.dll" named_guids \
// 重命名命名空间防止冲突
rename("EOF","adoEOF"),rename("BOF","adoBOF")
// 忽略警告
#pragma warning(default:4146)
// 使用命名空间
using namespace ADODB;
2、进行连接前需要对COM对象进行初始化
// 可以放到构造函数中
CoInitialize(NULL);
// 反初始化,一般放到析构函数中
CoUninitialize();
3、接下来可以进行连接了,有3个重要的对象,分别是:Connection(连接对象)、 Command(命令对象)、 Recordset(结果集对象)。ADO提供了相应的智能指针,我们使用的时候需要创建相应的变量(一般创建为成员变量)。
// 1、创建变量
_ConnectionPtr m_pConnection; // 连接对象智能指针
_CommandPtr m_pCommand; // 命令对象智能指针
_RecordsetPtr m_pRecordset; // 结果集对象的智能指针
4、首先我们创建连接对象,然后进行连接。
if (nullptr == m_pConnection)
{
try
{
if (!FAILED(m_pConnection.CreateInstance(__uuidof(Connection)))) // 创建对象
{
m_pConnection->CommandTimeout = 30; // 设置超时时间 单位秒
if (!FAILED(m_pConnection->Open((_bstr_t)m_szConnStr, “”, “”, adConnectUnspecified))) // 连接
{
return true;
}
}
}
catch(_com_error e)
{
char szLog[1024] = { 0 };
sprintf(szLog, "连接数据库错误:%s\n", e.Description());
return false;
}
}
说明:里面的Open函数中m_szConnStr
为数据库连接串,如果不知道的话可以参考我另外写的一篇常用数据库的连接字符串:点击这里-数据库常用连接字符串
Open函数中的adConnectUnspecified为一个枚举值ConnectOptionEnum
可选异步打开连接等
5、接下来需要对结果集对象进行初始化
if (nullptr == m_pRecordset)
{
try
{
if (!FAILED(m_pRecordset.CreateInstance(__uuidof(Recordset))))
{
return true;
}
}
catch (_com_error e)
{
char szLog[1024] = { 0 };
sprintf(szLog, "初始化结果集错误:%s\n", e.Description());
return false;
}
6、现在可以进行操作了(查询select,返回结果集的处理)
string SQL = "select * from emp"; // sql查询语句
long iRecordCount = 0; // 保存结果集数量
m_pRecordset->Open((_variant_t)SQL.c_str(), m_pConnection.GetInterfacePtr(), adOpenStatic/*adOpenDynamic*/, adLockOptimistic, adCmdText);
iRecordCount = m_pRecordset->RecordCount; // 获得结果集数量,可以用来判断是否查询有结果
if (iRecordCount < 1)
{
return false;
}
获得结果后我们就可以取数据了,如果是MFC程序我们使用CString
用来接收数据。
CString szTemp;
// 循环取结果,adoEOF是我们导入库的时候rename EOF的名字,用来判断是不是到结果集结束。
while(!m_pRecordset->adoEOF)
{
// 使用CString接收结果字符串
_variant_t var = m_pRecordset->GetCollect("ENAME");
var.ChangeType(VT_BSTR);
szTemp = var.bstrVal;
std::cout << szTemp << std::endl;
// 这个千万不能忘记,不然就是死循环
m_pRecordset->MoveNext();
}
如果使用char *
来接收字符串
char szTemp[1024] = { 0 };
// 循环取结果,adoEOF是我们导入库的时候rename EOF的名字,用来判断是不是到结果集结束。
while(!m_pRecordset->adoEOF)
{
// 使用char*接收结果字符串
_variant_t var = m_pRecordset->GetCollect("ENAME");
// 将结果集宽字节转换成多字节
WideCharToMultiByte(CP_ACP,0, var.bstrVal, -1, szTemp, sizeof(szTemp),NULL, NULL);
std::cout << szTemp << std::endl;
// 这个千万不能忘记,不然就是死循环
m_pRecordset->MoveNext();
}
7、如果我们使用的sql语句不需要返回结果集,如update、insert
等,此时我们可以直接使用connection
执行
long RefreshNum = 0; // 影响的行数
_variant_t varNum
string SQL = "update EMP set ename='Colin' where ename='SMITH'";
m_pConnection->Execute((_variant_t)SQL, &varNum, adCmdText);
RefreshNum = varNum.lVal; // 获得受影响的行数