当前位置: 首页 > news >正文

ADO 操作access

简介

DAO

DAO 是 Microsoft 早期推出的数据库访问技术,专门针对 Access(Jet 数据库引擎)进行了优化,对于 Access 数据库操作非常高效。

ADO

ADO(ActiveX Data Objects)是微软推出的一种基于 COM(Component Object Model)的数据库访问技术,用于在应用程序中实现对各种数据源的访问和操作。它提供了一套简单、高效的对象模型,使开发者能够轻松地连接数据库、执行查询、处理结果集等。

ADO 的主要特点:

  • 通用性强:支持多种数据库,包括 Access、SQL Server、Oracle、MySQL 等,无需针对不同数据库编写大量适配代码。
  • 基于 COM:作为 COM 组件,可在多种编程语言中使用,如 C++、VB、VBScript、ASP 等。
  • 轻量级:相比早期的 DAO(Data Access Objects),ADO 架构更简洁,性能更优,资源占用更少。
  • 灵活的对象模型:核心对象包括Connection(连接)、Command(命令)、Recordset(记录集)等,分工明确,易于理解和使用。
  • 支持断开连接的记录集:可将数据读取到本地后断开与数据库的连接,在本地处理数据,适合网络环境下减少连接开销。

ADO 的核心对象:

  • Connection:负责与数据库建立和管理连接,提供连接字符串配置、打开 / 关闭连接等功能。
  • Command:用于执行 SQL 语句或存储过程,支持参数化查询,可提高执行效率和安全性。
  • Recordset:表示查询返回的结果集,提供对记录的遍历、添加、修改、删除等操作,支持游标和锁定机制。
  • Parameter:配合Command使用,用于定义参数化查询中的参数,防止 SQL 注入。
  • Field:表示Recordset中的一个字段(列),用于访问字段的值和属性。

ADO 的典型使用流程:

  • 初始化 COM 环境(在 C++ 中需调用CoInitialize)。
  • 创建Connection对象,通过连接字符串连接到目标数据库。
  • 使用Command对象执行 SQL 命令,或直接通过Recordset执行查询。
  • 处理Recordset中的数据(遍历、修改等)。
  • 关闭记录集和连接,释放资源。
  • 反初始化 COM 环境(调用CoUninitialize)。

ADO 与其他数据库访问技术的对比:

  • 与 DAO 相比:ADO 更通用,支持多种数据库,而 DAO 主要针对 Access;ADO 性能更优,适合现代应用开发。
  • 与 ODBC 相比:ADO 是更高层次的封装,使用更简单,而 ODBC 是底层接口,需要更多的代码来实现相同功能。
  • 与 OLE DB 相比:ADO 是 OLE DB 的封装,简化了 OLE DB 的复杂操作,更易于上手。

导入msado15.dll

#import "msado15.dll" no_namespace rename("EOF", "adoEOF")
  • #import 是 Visual C++ 编译器的一个预处理指令,用于导入 COM 组件(.dll 或 .tlb 类型库文件)的类型信息。
  • “msado15.dll” 是 ADO 组件的动态链接库文件,包含了 ADO 的类型库信息。这个文件通常位于系统目录(如 C:\Program Files\Common Files\System\ado\)。
  • 执行这条指令后,编译器会自动生成两个文件
    • msado15.tlh:类型库头文件,包含了 ADO 接口、类、枚举等的声明(类似头文件)。
    • msado15.tli:实现文件,包含了一些包装函数的实现(无需手动包含,编译器会自动处理)。

no_namespace

指示编译器导入 ADO 类型时不使用其默认命名空间。
ADO 类型库的默认命名空间是 ADODB,如果不添加此参数,使用 ADO 组件时需要加上命名空间前缀(如 ADODB::_ConnectionPtr)。
使用 no_namespace 后,可以直接写 _ConnectionPtr 而无需 ADODB:: 前缀,简化代码。

rename(“EOF”, “adoEOF”)

用于重命名 ADO 中的 EOF 符号,避免与其他代码中的 EOF(如 C 标准库中的文件结束符)冲突。
ADOEOF(End Of File)表示记录集的末尾(当 Recordset 遍历到最后一条记录后,EOFtrue)。
C 标准库(如 <stdio.h>)中也有一个 EOF 宏(通常定义为 -1),表示文件操作的结束。如果不重命名,两者会产生命名冲突,导致编译错误。
重命名后,在代码中需使用 adoEOF 来表示 ADO 记录集的末尾(如 while (!pRs->adoEOF))。

初始化COM环境

CoInitialize(NULL);

_ConnectionPtr

用于管理数据库连接的智能指针类,封装了 ADO 的 Connection 对象,是 ADO 操作数据库的基础。它负责建立、管理和关闭与数据库的连接,同时提供事务处理等核心功能。

内部维护了对 COM 对象的引用计数,超出作用域时会自动释放资源(无需手动调用 Release(),但显式释放更规范)。

封装了数据库连接的核心功能:连接数据库、执行 SQL 命令、事务管理等。

常用方法和属性

创建 _ConnectionPtr 实例

使用 CreateInstance() 方法初始化对象,需指定 ADO Connection 类的 GUID

_ConnectionPtr pConn;
// 创建实例,__uuidof(Connection) 是 ADO Connection 类的 GUID
HRESULT hr = pConn.CreateInstance(__uuidof(Connection));
if (FAILED(hr)) {// 处理创建失败
}

连接数据库:Open() 方法

pConn->Open(_bstr_t(连接字符串), _bstr_t(用户名), _bstr_t(密码), 连接选项);
连接字符串

指定数据库类型、路径 / 地址等信息(因数据库而异)。

access

"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\test.accdb;"

SQL Server

"Provider=SQLOLEDB;Server=localhost;Database=test;Uid=sa;Pwd=123;"
用户名 / 密码

数据库登录凭证

连接选项

通常使用 adModeUnknown(默认值)。

关闭连接:Close() 方法

if (pConn->State == adStateOpen) { // 检查连接是否打开pConn->Close();
}

State 属性:返回连接状态,adStateOpen 表示已连接,adStateClosed 表示已关闭。

执行 SQL 命令:Execute() 方法

直接执行 SQL 语句(适合无需返回结果集的操作,如 CREATE TABLE、INSERT、UPDATE、DELETE 等):

// 语法:_RecordsetPtr Execute(_bstr_t CommandText, VARIANT* RecordsAffected, long Options);
_variant_t RecordsAffected;
// 执行创建表操作
pConn->Execute("CREATE TABLE Users (ID INT, Name TEXT(50), Age INT)", &RecordsAffected, adCmdText);
// 执行插入操作
pConn->Execute("INSERT INTO Users VALUES (1, '张三', 25)", &RecordsAffected, adCmdText);

参数:

  • CommandText:SQL 语句或存储过程名。
  • RecordsAffected:返回受影响的行数(可选)。
  • Options:命令类型,adCmdText 表示 SQL 语句,adCmdStoredProc 表示存储过程。

返回值:如果 SQL 是查询语句(SELECT),返回 _RecordsetPtr 结果集;否则返回 NULL

事务管理

_ConnectionPtr 提供事务的开始、提交和回滚功能,确保多个操作的原子性:

try {pConn->BeginTrans(); // 开始事务// 执行一系列操作pConn->Execute("UPDATE Accounts SET Balance = Balance - 100 WHERE ID = 1", NULL, adCmdText);pConn->Execute("UPDATE Accounts SET Balance = Balance + 100 WHERE ID = 2", NULL, adCmdText);pConn->CommitTrans(); // 提交事务(所有操作生效)
} catch (_com_error& e) {pConn->RollbackTrans(); // 回滚事务(所有操作撤销)std::cout << "事务失败: " << (const char*)e.Description() << std::endl;
}

其他常用属性

  • ConnectionString:获取或设置连接字符串。
  • Version:返回 ADO 版本号。
  • DefaultDatabase:设置或获取默认数据库。

ACCESS数据库引擎

在连接 Access 数据库时,最常用的 Jet OLEDB(Microsoft.Jet.OLEDB.4.0)和 ACE OLEDB(Microsoft.ACE.OLEDB.12.0/16.0)驱动

连接数据库

Microsoft.ACE.OLEDB.12.0(推荐,支持所有格式)

适用于 Access 2007 + 的.accdb 文件和旧版.mdb 文件,支持 32 位和 64 位程序:

_ConnectionPtr pConn;
pConn.CreateInstance(__uuidof(Connection));
// 使用ACE驱动连接.accdb
pConn->Open(_T("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Database\\db1.accdb;")_T("Jet OLEDB:System Database=Database\\workgroup.mdw;")  // 工作组文件路径_T("Jet OLEDB:Database Password=dbpassword;"),             // 数据库密码(若有)_T("username"),  // 用户名(如 Admin)_T("userpassword"),  // 用户密码adModeUnknown
);

Microsoft.Jet.OLEDB.4.0(适用于.mdb 文件)

// C++ ADODB连接示例
_ConnectionPtr pConn;
pConn->Open(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Database\\db1.mdb;")_T("Jet OLEDB:System Database=Database\\workgroup.mdw;")  // 工作组文件路径_T("Jet OLEDB:Database Password=dbpassword;"),             // 数据库密码(若有)_T("username"),  // 用户名_T("userpassword"),  // 用户密码adModeUnknown
);

_CommandPtr

_CommandPtr 是 ADO(ActiveX Data Objects)中用于执行数据库命令的智能指针类,封装了 ADOCommand 对象。它主要用于处理 SQL 语句、存储过程等数据库命令,支持参数化查询,是 ADO 中执行复杂数据库操作的核心组件。

  • 执行 SQL 语句(查询、插入、更新、删除等)或调用存储过程。
  • 支持参数化查询(通过 Parameters 集合),避免 SQL 注入,提高执行效率。
  • 可将命令与特定连接关联,也可动态指定连接。
  • 执行后可返回结果集(通过 _RecordsetPtr)或受影响的行数。

CreateInstance

_CommandPtr pCmd;
HRESULT hr = pCmd.CreateInstance(__uuidof(Command));
if (FAILED(hr)) {// 处理创建失败
}

关联数据库连接:ActiveConnection 属性

_CommandPtr 需与一个打开的数据库连接关联(通过 _ConnectionPtr 或连接字符串):

// 方式1:关联已打开的_ConnectionPtr
pCmd->ActiveConnection = pConn;  // pConn 是已打开的连接// 方式2:直接指定连接字符串
pCmd->ActiveConnection = _bstr_t("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\test.accdb;");

设置命令内容:CommandText CommandType

  • CommandText:指定要执行的命令(SQL 语句、存储过程名或表名)。
  • CommandType:指定命令类型(提高解析效率,可选):
    • adCmdText:SQL 语句(默认值)。
    • adCmdStoredProc:存储过程。
    • adCmdTable:表名(等效于 SELECT * FROM 表名)。
// 示例1:执行SQL语句
pCmd->CommandText = "SELECT * FROM Users WHERE Age > ?";  // 带参数的查询
pCmd->CommandType = adCmdText;// 示例2:调用存储过程
pCmd->CommandText = "sp_InsertUser";  // 存储过程名
pCmd->CommandType = adCmdStoredProc;

参数化查询:Parameters 集合

CreateParameter():创建参数对象。
Append():将参数添加到 Parameters 集合。
SetParamValue():设置参数值(或直接通过索引 / 名称访问)。
// 1. 添加参数(假设SQL为"SELECT * FROM Users WHERE Age > ? AND Name LIKE ?")
pCmd->Parameters->Append(pCmd->CreateParameter("AgeParam",        // 参数名(可选)adInteger,         // 数据类型(整数)adParamInput,      // 参数方向(输入)sizeof(int),       // 长度(仅字符串等类型需要)18                 // 默认值(可选)
));pCmd->Parameters->Append(pCmd->CreateParameter("NameParam", adVarChar,         // 字符串类型adParamInput, 50,                // 字符串长度"%张%"             // 默认值
));// 2. 动态修改参数值(执行前)
pCmd->Parameters->GetItem("AgeParam")->Value = _variant_t(20);
// 或通过索引访问(0-based)
pCmd->Parameters->GetItem(1)->Value = _variant_t("%李%");

执行命令:Execute() 方法

// 语法:_RecordsetPtr Execute(VARIANT* RecordsAffected, VARIANT* Parameters, long Options);
_variant_t RecordsAffected;  // 用于接收受影响的行数
_RecordsetPtr pRs;// 执行查询命令(返回结果集)
pRs = pCmd->Execute(&RecordsAffected, NULL, adCmdText);// 执行非查询命令(如INSERT/UPDATE/DELETE,返回NULL)
pCmd->Execute(&RecordsAffected, NULL, adCmdText);
long affected = (long)RecordsAffected;  // 获取受影响的行数

释放资源:Release() 与状态检查

if (pCmd) {pCmd->Cancel();  // 取消正在执行的命令(如需)pCmd.Release();  // 释放智能指针
}

示例

#import "msado15.dll" no_namespace rename("EOF", "adoEOF")
#include <iostream>
#include <atlbase.h>int main() {CoInitialize(NULL);_ConnectionPtr pConn;_CommandPtr pCmd;_RecordsetPtr pRs;try {// 1. 连接数据库pConn.CreateInstance(__uuidof(Connection));pConn->Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\test.accdb;", "", "", adModeUnknown);// 2. 创建并配置Command对象pCmd.CreateInstance(__uuidof(Command));pCmd->ActiveConnection = pConn;  // 关联连接pCmd->CommandText = "SELECT * FROM Users WHERE Age > ?";  // 带参数的SQLpCmd->CommandType = adCmdText;// 3. 添加参数pCmd->Parameters->Append(pCmd->CreateParameter("AgeParam", adInteger, adParamInput, sizeof(int), 20));// 4. 执行查询,获取结果集pRs = pCmd->Execute(NULL, NULL, adCmdText);// 5. 遍历结果std::cout << "年龄大于20的用户:" << std::endl;while (!pRs->adoEOF) {std::cout << "ID: " << (long)pRs->Fields->GetCollect("ID")<< ", Name: " << (const char*)_bstr_t(pRs->Fields->GetCollect("Name"))<< ", Age: " << (long)pRs->Fields->GetCollect("Age") << std::endl;pRs->MoveNext();}// 6. 执行插入命令(非查询)pCmd->CommandText = "INSERT INTO Users (Name, Age) VALUES (?, ?)";pCmd->Parameters->Clear();  // 清除原有参数pCmd->Parameters->Append(pCmd->CreateParameter("Name", adVarChar, adParamInput, 50, "赵六"));pCmd->Parameters->Append(pCmd->CreateParameter("Age", adInteger, adParamInput, sizeof(int), 35));_variant_t affected;pCmd->Execute(&affected, NULL, adCmdText);std::cout << "\n插入成功,受影响行数:" << (long)affected << std::endl;// 7. 释放资源pRs->Close();pCmd.Release();pConn->Close();} catch (_com_error& e) {std::cout << "错误: " << (const char*)e.Description() << std::endl;}CoUninitialize();return 0;
}

_RecordsetPtr

_RecordsetPtr 是 ADO(ActiveX Data Objects)中用于处理数据库查询结果集的智能指针类,封装了 ADO 的 Recordset 对象。它是 ADO 中最常用的组件之一,负责存储查询返回的数据,并提供对记录的遍历、修改、添加、删除等操作。

  • 表示从数据库查询返回的结果集(类似表格数据,由行和列组成)。
  • 提供游标(Cursor)功能,支持在结果集中移动(如首行、尾行、指定行)。
  • 支持对记录的增删改操作,并能将修改提交到数据库。
  • 可独立使用(直接执行查询)或配合 _CommandPtr 使用(执行命令后获取结果)。

CreateInstance()

_RecordsetPtr pRs;
HRESULT hr = pRs.CreateInstance(__uuidof(Recordset));
if (FAILED(hr)) {// 处理创建失败
}

open

HRESULT Open(const _variant_t& Source,       // 数据源const _variant_t& ActiveConnection,  // 连接对象enum CursorTypeEnum CursorType,      // 游标类型enum LockTypeEnum LockType,          // 锁定类型long Options                         // 命令执行选项
);

Source

指定要打开的记录集来源,常见类型:

  • SQL 语句:如"SELECT * FROM HistoryRecord"
  • 表名:如"HistoryRecord"(需配合adCmdTable选项)
  • 存储过程名:如"sp_GetUserInfo"(需配合adCmdStoredProc选项)
  • Command 对象:已创建的_CommandPtr对象

ActiveConnection(连接对象,可选)

指定记录集使用的数据库连接,有两种设置方式:
直接传入连接对象

_variant_t((IDispatch*)theApp.m_pConnection, TRUE)

传入连接字符串

_variant_t("Provider=SQLOLEDB;Data Source=.;Database=Test;Uid=sa;Pwd=123;")

pConn.GetInterfacePtr()

pRs->Open("SELECT * FROM Users", pConn.GetInterfacePtr(),  // 已打开的_ConnectionPtradOpenDynamic,            // 动态游标adLockOptimistic,         // 乐观锁定adCmdText                 // 第一个参数是SQL语句
);

CursorType(游标类型,可选,默认adOpenForwardOnly)

决定记录集的遍历方式和功能,常用类型:

  • adOpenForwardOnly:仅向前游标(默认),只能向前遍历记录,效率最高。
  • adOpenStatic:静态游标,创建记录的静态副本,可前后遍历,但不反映其他用户的修改。
  • adOpenKeyset:键集游标,可前后遍历,能反映其他用户的记录更新,但不显示新增记录。
  • adOpenDynamic:动态游标,实时反映所有用户对记录的增删改,功能最强但效率较低。

LockType(锁定类型,可选,默认adLockReadOnly)

控制记录集的编辑权限和锁定机制,常用类型:

  • adLockReadOnly:只读(默认),不能修改记录。
  • adLockPessimistic:悲观锁定,编辑记录时立即锁定该记录,防止其他用户修改。
  • adLockOptimistic:乐观锁定,仅在调用Update时锁定记录,适合多用户环境。
  • adLockBatchOptimistic:批量乐观锁定,允许批量修改后统一提交(需配合UpdateBatch)。

Options(命令执行选项,可选,默认-1)

指定Source参数的类型,避免 ADODB 自动判断,提高效率并防止错误:

  • adCmdText:Source是 SQL 命令文本(如"SELECT …")。
  • adCmdTable:Source是表名(如"HistoryRecord")。
  • adCmdStoredProc:Source是存储过程名。
  • adCmdUnknown:未知类型(ADODB 会自动判断,不推荐)。

遍历结果集

  • adoEOF:布尔值,true 表示已到达结果集末尾(需配合 rename(“EOF”, “adoEOF”) 使用)。
  • MoveFirst():移动到第一条记录。
  • MoveLast():移动到最后一条记录。
  • MoveNext():移动到下一条记录。
  • MovePrevious():移动到上一条记录。
  • Move(n):移动 n 条记录(正数向前,负数向后)。
// 遍历所有记录
pRs->MoveFirst();  // 移动到首行
while (!pRs->adoEOF) {// 读取字段值(见下文“获取字段值”)_variant_t varID = pRs->Fields->GetItem("ID")->Value;_variant_t varName = pRs->Fields->GetItem("Name")->Value;std::cout << "ID: " << (long)varID << ", Name: " << (const char*)_bstr_t(varName) << std::endl;pRs->MoveNext();  // 移动到下一行
}

字段值

_RecordsetPtr::Fields 是记录集中所有字段(Field 对象)的集合。

FieldsPtr fds = rs->Fields;          // 智能指针,自动释放
long n = fds->Count;                 // 字段个数for (long i = 0; i < n; ++i)
{FieldPtr fld = fds->GetItem(i);  // 或 fds->Item[i]_bstr_t name  = fld->Name;       // 字段名DataTypeEnum type = fld->Type;   // 数据类型long size = fld->DefinedSize;    // 长度printf("%d  %s  %d\n", i, (char*)name, type);
}
rs->Fields->Item["Age"]->Value = _variant_t((short)30);
// 等价于:
rs->PutCollect("Age", _variant_t((short)30));

GetItem

// 通过字段名获取
_variant_t varID = pRs->Fields->GetItem("ID")->Value;
_variant_t varName = pRs->Fields->GetItem("Name")->Value;// 通过索引获取(0表示第一列)
_variant_t varAge = pRs->Fields->GetItem(2)->Value;// 转换为C++类型
long id = (long)varID;               // 整数
std::string name = (const char*)_bstr_t(varName);  // 字符串
int age = (long)varAge;              // 整数

设置

pRs->Fields->GetItem("Name")->Value = _variant_t("新名称");
pRs->Fields->GetItem("Age")->Value = _variant_t((long)30);

GetCollect

_variant_t value = m_pRecordset->GetCollect("字段名");_variant_t vName = m_pRecordset->GetCollect("FirstName");
CString strName = (LPCTSTR)(_bstr_t)vName;

PutCollect

m_pRecordset->PutCollect("FirstName", _variant_t("John"));

比较

  • GetItem 是基础方法,获取字段对象后可做更多操作(如查看字段类型),但代码稍繁琐。
  • GetCollectPutCollect 是快捷方法,直接操作字段值,代码更简洁,适合大多数仅需读写值的场景。
    实际开发中,若仅需读写字段值,优先使用 GetCollectPutCollect;若需处理字段元数据,再使用 GetItem

添加新记录:AddNew() + Update()

// 1. 开始添加新记录
pRs->AddNew();// 2. 设置字段值
pRs->Fields->GetItem("ID")->Value = _variant_t((long)3);
pRs->Fields->GetItem("Name")->Value = _variant_t("王五");
pRs->Fields->GetItem("Age")->Value = _variant_t((long)28);// 3. 提交到数据库
pRs->Update();
m_pRecordset->AddNew();
m_pRecordset->PutCollect("EmployeeID", _variant_t((long)10));
m_pRecordset->PutCollect("FirstName", _variant_t("Mary"));
m_pRecordset->PutCollect("LastName", _variant_t("Williams"));
m_pRecordset->Update();

修改现有记录:Edit() + Update()

// 1. 移动到要修改的记录
pRs->MoveFirst();// 2. 进入编辑模式
pRs->Edit();// 3. 修改字段值
pRs->Fields->GetItem("Age")->Value = _variant_t((long)29);// 4. 提交修改
pRs->Update();

批量更新

prs->CursorLocation = adUseClient;          // 客户端游标
prs->Open("SELECT * FROM LogTable",conn.GetInterfacePtr(),adOpenStatic,adLockBatchOptimistic);           // 批模式while (!prs->EndOfFile)
{prs->PutCollect("Status", _variant_t("Processed"));prs->MoveNext();
}
prs->UpdateBatch(adAffectAll);              // 一次性提交

删除记录:Delete()

// 1. 移动到要删除的记录
pRs->MoveFirst();// 2. 删除当前记录
pRs->Delete(adAffectCurrent);  // adAffectCurrent表示仅删除当前记录// 3. 移动游标(删除后需手动移动,否则可能出错)
pRs->MoveNext();

关闭结果集:Close()

if (pRs->State == adStateOpen) {  // 检查是否打开pRs->Close();
}
pRs.Release();  // 释放智能指针

其他常用属性

  • RecordCount:返回结果集中的记录总数(需配合 OpenStaticadOpenKeyset 游标)。
  • BOF:布尔值,true 表示已定位到结果集开头之前。
  • Fields->Count:返回字段(列)的数量。
  • AbsolutePosition:获取或设置当前记录的绝对位置(从 1 开始)。

示例

#import "msado15.dll" no_namespace rename("EOF", "adoEOF")
#include <iostream>
#include <atlbase.h>int main() {CoInitialize(NULL);_ConnectionPtr pConn;_RecordsetPtr pRs;try {// 1. 连接数据库pConn.CreateInstance(__uuidof(Connection));pConn->Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\test.accdb;", "", "", adModeUnknown);// 2. 执行查询获取结果集pRs.CreateInstance(__uuidof(Recordset));pRs->Open("SELECT * FROM Users", pConn.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText);// 3. 遍历记录std::cout << "查询结果(共 " << pRs->RecordCount << " 条):" << std::endl;while (!pRs->adoEOF) {std::cout << "ID: " << (long)pRs->Fields->GetItem("ID")->Value<< ", Name: " << (const char*)_bstr_t(pRs->Fields->GetItem("Name")->Value)<< ", Age: " << (long)pRs->Fields->GetItem("Age")->Value << std::endl;pRs->MoveNext();}// 4. 添加新记录pRs->AddNew();pRs->Fields->GetItem("ID")->Value = _variant_t((long)3);pRs->Fields->GetItem("Name")->Value = _variant_t("王五");pRs->Fields->GetItem("Age")->Value = _variant_t((long)28);pRs->Update();std::cout << "\n添加新记录成功" << std::endl;// 5. 关闭资源pRs->Close();pConn->Close();} catch (_com_error& e) {std::cout << "错误: " << (const char*)e.Description() << std::endl;}pRs.Release();pConn.Release();CoUninitialize();return 0;
}
http://www.xdnf.cn/news/1385695.html

相关文章:

  • 选华为实验工具:eNSP Pro 和社区在线实验哪个更适合?
  • 《华为战略管理法:DSTE 实战体系》读书笔记
  • 第二章 Vue + Three.js 实现鼠标拖拽旋转 3D 立方体交互实践
  • FDTD_mie散射_项目研究(1)
  • DirectX修复工具官方中文增强版下载!下载安装教程(附安装包),0xc000007b错误解决办法
  • 【python+requests】接口自动化测试:三步用代理工具快速定位问题
  • Linux 软件编程(十四)网络编程:数据存储与 SQLite 数据库
  • 【C++】类与对象(上)
  • Python- Visual Studio Code配置Anaconda
  • Vue 实战:优雅实现无限层级评论区,支持“显示全部”分页递归加载
  • simd笔记
  • 使用生成对抗网络增强网络入侵检测性能
  • 【开题答辩全过程】以 基于Python的美食点评系统为例,包含答辩的问题和答案
  • 【数据结构与算法-Day 20】从零到一掌握二叉树:定义、性质、特殊形态与存储结构全解析
  • Hadoop(六)
  • T06_循环神经网络
  • 基于博客系统的自动化测试项目
  • Selenium无法定位元素的几种解决方案
  • C# 日志写入loki
  • 力扣452:用最少数量的箭射爆气球(排序+贪心)
  • 如何编译和使用 tomcat-connectors-1.2.32 源码(连接 Apache 和 Tomcat)​附安装包下载
  • 数据质检之springboot通过yarn调用spark作业实现数据质量检测
  • Dify 1.8.0 全网首发,预告发布
  • 2024-06-13-debian12安装Mariadb-Galera-Cluster+Nginx+Keepalived高可用多主集群
  • 动态UI的秘诀:React中的条件渲染
  • 在PostgreSQL中使用分区技术
  • 【三维渲染技术讨论】Blender输出的三维文件里的透明贴图在Isaac Sim里会丢失, 是什么原因?
  • Blender建模软件基本操作--学习笔记1
  • 查看docker容器内部的环境变量并向docker容器内部添加新的环境变量
  • 第十二节 Spring 注入集合