VC++下使用ADO操作数据库主要要用到 _ConnectionPtr,_CommandPtr,_RecordsetPtr三个ADO对象指针,我查找了相关资料,发现网上源码很多,但是都相对凌乱,于是自己也试着写了一个简单的例子,有什么问题,希望大佬们指正

关于三个ADO对象指针的介绍:

1,_ConnectionPtr接口返回一个记录集或一个空指针。通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。使用 _ConnectionPtr接口返回一个记录集不是一个好的使用方法。对于要返回记录的操作通常用_RecordserPtr来实现。而用,_ConnectionPtr操作时要想得到记录条数得遍历所有记录,而用_RecordserPtr时不需要。

2,_CommandPtr接口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,你可以利用全局 _ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。如果你只执行一次或几次数据访问操作,后者是比较好的选择。但 如果你要频繁访问数据库,并要返回很多记录集,那么,你应该使用全局_ConnectionPtr接口创建一个数据连接,然后使用_CommandPtr 接口执行存储过程和SQL语句。

3,_RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如 记录锁定,游标控制等。同_CommandPtr接口一样,它不一定要使用一个已经创建的数据连接,可以用一个连接串代替连接指针赋给 _RecordsetPtr的connection成员变量,让它自己创建数据连接。如果你要使用多个记录集,最好的方法是同Command对象一样使用 已经创建了数据连接的全局_ConnectionPtr接口,然后使用_RecordsetPtr执行存储过程和SQL语句。

代码:(如何有小伙伴也会使用到VC++操作ADO数据库可以参考微软官方文档,我这边也参考了上面的源码:https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/ado-code-examples-in-visual-c?view=sql-server-2017)

/*
VC++下使用ADO操作数据库简单实例
author:chenyuan
1,向User表插入一条数据
2,查询User表并输出结果集
*/
#include "stdafx.h"
//stdafx.h" 包含如下文件
//#include "targetver.h"
//#include <stdio.h>
//#include <tchar.h>
//#include <icrsint.h>
//#include <iostream>
//#include <iomanip>
//#include <string>
using namespace std;
//(1)、引入ADO类
#import "c:\program files\common files\system\ado\msado15.dll" \
no_namespace \
rename ("EOF", "adoEOF") #define ConStr "Driver={sql server};server=127.0.0.1,1433;uid=sa;pwd=123456;database=YLTD2;"
//"Provider=SQLOLEDB;Server=127.0.0.1,1433;Database=PBMS;uid=sa;pwd=pp471006459;";
//"Provider=SQLOLEDB.1;Password=pp471006459;Persist Security Info=True;User ID=sa;"
//"Initial Catalog=PBMS;Data Source=127.0.0.1,1433";
//以上这三条strConnect语句都可以用
//要注意修改用户名uid、密码pwd、数据库名database #define GetValue(ptr,name) ((char*)(_bstr_t)(ptr->GetCollect(name))) int ExcuteStr1(_bstr_t sql);
int ExcuteStr2(variant_t sql);
int main()
{
ExcuteStr1("INSERT [dbo].[User]([Name],[DisplayName],[Password],[Status],[Sex],[Tel],[Mobile],[Email],[RoleID]) Values('C++Test','yuanker','123456',1,1,15911111111,1111111,111111,1)"); ExcuteStr2("SELECT * FROM [dbo].[User]");
system("pause");
return ;
} int ExcuteStr1(_bstr_t sql) {
//定义ADO对象指针。初始化定义上的指针。
_RecordsetPtr m_pRecordset = NULL;
_ConnectionPtr m_pConnection = NULL;
_CommandPtr m_pCommand = NULL;
HRESULT hr = S_OK;
if (FAILED(CoInitialize(NULL)))//CoInitialize用来初始化当前线程COM库,后面CoUninitialize与之对应,用来关闭当前线程的COM库
return -;//如果初始化失败则返回-1
//初始化连接参数
try
{
if (SUCCEEDED(hr)) {
_bstr_t strConnect = ConStr;
//创建实例
m_pConnection.CreateInstance(__uuidof(Connection));
/*打开连接
ConnectionString 可选,字符串,包含连接信息。参阅 ConnectionString 属性可获得有效设置的详细信息。
UserID 可选,字符串,包含建立连接时所使用用户名。
Password 可选,字符串,包含建立连接时所使用密码。
Options 可选,ConnectOptionEnum 值。决定该方法是在连接建立之后(异步)还是连接建立之前(同步)返回。adConnectUnspecified:(默认)同步打开连接。adAsyncConnect:异步打开连接。ConnectComplete 事件可以用于决定连接何时可用。
*/
m_pConnection->Open(strConnect, "", "", adConnectUnspecified);
m_pCommand.CreateInstance(__uuidof(Command));
// 将库连接赋于它
m_pCommand->ActiveConnection = m_pConnection;
// SQL语句
m_pCommand->CommandText = sql;
// 执行SQL语句,返回记录集
/*adCmdText: 表明CommandText是文本命令
adCmdTable : 表明CommandText是一个表名
adCmdProc : 表明CommandText是一个存储过程
adCmdUnknown : 未知*/
m_pRecordset = m_pCommand->Execute(NULL, NULL, adCmdText);
if (m_pRecordset)
if (m_pRecordset->State == adStateOpen)
m_pRecordset->Close();
if (m_pConnection)
if (m_pConnection->State == adStateOpen)
m_pConnection->Close();
CoUninitialize();
}
}
catch (_com_error &e)
{
cout << e.Description() << endl;
return -;
}
return ;
} int ExcuteStr2(variant_t sql) {
//定义ADO对象指针。初始化定义上的指针。
_RecordsetPtr m_pRecordset = NULL;
_ConnectionPtr m_pConnection = NULL;
HRESULT hr = S_OK;
if (FAILED(CoInitialize(NULL)))//CoInitialize用来初始化当前线程COM库,后面CoUninitialize与之对应,用来关闭当前线程的COM库
return -;//如果初始化失败则返回-1
//初始化连接参数
try
{
if (SUCCEEDED(hr)) {
_bstr_t strConnect = ConStr;
m_pConnection.CreateInstance(__uuidof(Connection));
/*打开连接
ConnectionString 可选,字符串,包含连接信息。参阅 ConnectionString 属性可获得有效设置的详细信息。
UserID 可选,字符串,包含建立连接时所使用用户名。
Password 可选,字符串,包含建立连接时所使用密码。
Options 可选,ConnectOptionEnum 值。决定该方法是在连接建立之后(异步)还是连接建立之前(同步)返回。adConnectUnspecified:(默认)同步打开连接。adAsyncConnect:异步打开连接。ConnectComplete 事件可以用于决定连接何时可用。
*/
m_pConnection->Open(strConnect, "", "", adConnectUnspecified);
m_pRecordset.CreateInstance(__uuidof(Recordset));
/*
①Source是数据查询字符串
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
③CursorType光标类型,它可以是以下值之一, 请看这个枚举结构:
enum CursorTypeEnum
{
adOpenUnspecified = -1,///不作特别指定
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这 种方式可以提高浏览速度。但诸如BookMark, RecordCount, AbsolutePosition, AbsolutePage都不能使用
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的 操作对你是可见的。
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操 作对你的记录集来说是不可见的。
};
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
enum LockTypeEnum
{
adLockUnspecified = -1,///未指定
adLockReadOnly = 1,///只读记录集
adLockPessimistic = 2, 悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
adLockOptimistic = 3, 乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数
据的更新、插入、删除等动作
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
};
5.option可以取以下值
adCmdText : 表明CommandText是文本命令
adCmdTable : 表明CommandText是一个表名
adCmdProc : 表明CommandText是一个存储过程
adCmdUnknown : 未知
*/
m_pRecordset->Open(sql, (IDispatch *)m_pConnection, adOpenDynamic, adLockOptimistic, adCmdText);
m_pRecordset->MoveFirst();
while (!m_pRecordset->adoEOF)//此处adoEOF为上面的 rename("EOF","adoEOF")
{
/*string Name = (char*)(_bstr_t)(m_pRecordset->Fields->GetItem(_variant_t("Name"))->Value);
string Password = (char*)(_bstr_t)(m_pRecordset->Fields->GetItem(_variant_t("Password"))->Value);*/
string ID = GetValue(m_pRecordset, "ID");
string Name = GetValue(m_pRecordset,"Name");
string Password = GetValue(m_pRecordset, "Password");
string Sex = GetValue(m_pRecordset, "Sex");
cout << "编号:" << ID << " 姓名:" << Name << " 密码:" << Password << " 性别:" << Sex << endl;
m_pRecordset->MoveNext();
}
//关闭结果集
if (m_pRecordset)
if (m_pRecordset->State == adStateOpen)
m_pRecordset->Close();
if (m_pConnection)
if (m_pConnection->State == adStateOpen)
m_pConnection->Close();
CoUninitialize();
}
}
catch (_com_error &e)
{
cout << e.Description() << endl;
return -;
}
return ;
}

附:

附录来源:http://blog.csdn.net/umbrella1984/archive/2005/05/29/383628.aspx

1、_variant_t

(1)、一般传给这3个指针的值都不是MFC直接支持的数据类型,而要用_variant_t转换一下
_variant_t(XX)可以把大多数类型的变量转换成适合的类型传入:
(2)、_variant_t var;_variant_t -> long: (long)var;
_variant_t -> CString: CString strValue = (LPCSTR)_bstr_t(var);
CString -> _variant_t: _variant_t(strSql);
2、BSTR宽字符串与CString相互转换

BSTR bstr;
CString strSql;
CString -> BSTR: bstr = strSql.AllocSysString();
BSTR -> CString: strSql = (LPCSTR)bstr;
3、_bstr_t与CString相互转换

_bstr_t bstr;
CString strSql;
CString -> _bstr_t: bstr = (_bstr_t)strSql;
_bstr_t -> CString: strSql = (LPCSTR)bstr;
4、关于时间

Access:表示时间的字符串#2004-4-5#
Sql:表示时间的字符串”2004-4-5”
DateField(时间字段) select * from my_table where DateField > #2004-4-10#

VC++下使用ADO操作数据库的更多相关文章

  1. [转]VC++下使用ADO操作数据库

    (1).引入ADO类 1 2 3 #import "c:program filescommon filessystemadomsado15.dll" no_namespace re ...

  2. VC中使用ADO操作数据库的方法 SQL2000

    (1).引入ADO类 #import "c:\program files\common files\system\ado\msado15.dll" \ no_namespace \ ...

  3. VC中使用ADO操作数据库的方法

    源地址:http://blog.csdn.net/xiaobai1593/article/details/7459862 准备工作: (1).引入ADO类 #import "c:\progr ...

  4. 在VC下采用ADO实现BLOB(Binary)数据的存储,读取,修改,删除。

    在VC下采用ADO实现BLOB(Binary)数据的存储,读取,修改,删除. 作者:邵盛松 2009-09-05 前言 1关于的BLOB(Binary)数据的存储和读取功能主要参考了MSDN上的一篇& ...

  5. VC++下封装ADO类以及使用方法

    操作系统:windows 7软件环境:visual studio 2008 .Microsoft SQL 2005本次目的:介绍一个已经封装的ADO类,简单说明怎么导入使用 首先声明一下,这个封装的A ...

  6. 用ADO操作数据库的方法步骤(ZT)

    http://www.cppblog.com/changshoumeng/articles/113437.html 学习ADO时总结的一些经验 用ADO操作数据库的方法步骤 ADO接口简介 ADO库包 ...

  7. 摘:用ADO操作数据库的方法步骤

    用ADO操作数据库的方法步骤 ADO接口简介 ADO库包含三个基本接口:_ConnectionPtr接口._CommandPtr接口和_RecordsetPtr接口. _ConnectionPtr接口 ...

  8. 用ADO操作数据库的方法步骤

    用ADO操作数据库的方法步骤 学习ADO时总结的一些经验 - 技术成就梦想 - 51CTO技术博客 http://freetoskey.blog.51cto.com/1355382/989218   ...

  9. 摘:C++:用ADO操作数据库的方法步骤

      ADO接口简介 ADO库包含三个基本接口:_ConnectionPtr接口._CommandPtr接口和_RecordsetPtr接口. _ConnectionPtr接口返回一个记录集或一个空指针 ...

随机推荐

  1. 开发工具 -- PyDev的使用

    1.创建PyDev工程 2.创建源文件夹src 3.新建.py文件 其他注意事项 1.设置字体大小 2.显示行号Ctrl + F10 3.编码设置为UTF-8 4.最好将工程创建到默认工作空间 5.总 ...

  2. Glide的用法

    最基本用法 glide采用的都是流接口方式 简单的从网络加载图片 Glide.with(context).load(internetUrl).into(targetImageView); 从文件加载 ...

  3. 在k8s中搭建可解析hostname的DNS服务

    2016-01-25更新 上篇文章总结k8s中搭建hbase时,遇到Pod中hostname的DNS解析问题,本篇将通过修改kube2sky源码来解决这个问题. 1 前言 kube2sky在Githu ...

  4. Golang gRPC 和 gRPC-gateway 结合使用

    一.安装 go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway go get -u github.com/g ...

  5. php的数组变量

    数组就是存储同一类型的多个变量的 一种特殊的类型 php的数组有两种形态 1.普通类型 eg:$cars = array("Volvo","BMW"," ...

  6. C/C++中的常量到底存在了什么地方

    一般来说,基本类型(整型.字符型等)常量会在编译阶段被编译成立即数,占的是代码段的内存.(代码段是只读的,而且不允程序员获取代码段的地址,所以在c++中,尽量不为const分配数据段的内存,但是一旦取 ...

  7. Hive导入数据的四种方法

    Hive的几种常见的数据导入方式这里介绍四种:(1).从本地文件系统中导入数据到Hive表:(2).从HDFS上导入数据到Hive表:(3).从别的表中查询出相应的数据并导入到Hive表中:(4).在 ...

  8. IDEA中Maven切换国内源

    国内访问Maven仓库非常慢,笔者今天忘记切换国内源更新Maven仓库竟然更新了一下午.如果改成国内的源,那么很快就更新完成了. 在IDEA中打开“Settings”(快捷键++): 在搜索框中输入“ ...

  9. [日常] json_encode对中文和引号的处理差异研究

    json_encode()1.默认就是把所有 ASCII 可显示字符以外的统统转义为 Unicode如果把那些字符转义为 Unicode 之后,无论文件编码是否一致,都不会出现乱码,因此中文转成Uni ...

  10. Java基础教程(21)--泛型

    一.为什么使用泛型   泛型意味着编写的代码可以被很多不同类型的对象所重用.例如,我们不希望为存放String和Integer对象的集合设计不同的类.现在的ArrayList类可以存放任何类型的对象, ...