_RecordsetPtr m_pRecordset; //记录集
CString strid;
_ConnectionPtr connection;
m_pRecordset.CreateInstance(__uuidof(Recordset )); //创建实例
m_pRecordset->Open("SELECT * FROMusers",connection.GetInterfacePtr
(),adOpenStatic,adLockOptimistic,adCmdText);//执行SQL语句,得到记录集, connection必须已和数
据库连接
/*************原型*****************/
Open方法的原型是这样的:
HRESULT Recordset15::Open( const _variant_t & Source, const _variant_t & ActiveConnection,
enum CursorTypeEnum CursorType, enum LockTypeEnumLockType, long Options )
/***********************************/
/************************************************/
①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:未知
/******************************************************/
while(!m_pRecordset->adoEOF)///这里为什么是adoEOF而不是EOF呢?还记得rename("EOF","adoEOF")这
一句吗?
{
vID = m_pRecordset->GetFields()->GetItem((long)0).Value;///取得第1列的值,从0开始计数,
strid = (TCHAR*)(_bstr_t)vID //转换为字符串
vname = m_pRecordset->GetFields()->GetItem((long)0).name;//取得第一列属性名
//以直接给出列的名称,如下一行
vUsername = m_pRecordset->GetCollect("username");///取得username字段的值
m_pRecordset->MoveNext();///移到下一条记录
}
m_pRecordset->GetFields()->Count//获得一条记录的字段数
m_pRecordset->MoveFirst();///移到首条记录
m_pRecordset->Delete(adAffectCurrent);///删除当前记录
///添加三条新记录并赋值
for(int i=0;i<3;i++)
{
m_pRecordset->AddNew();///添加新记录
m_pRecordset->PutCollect("ID",_variant_t((long)(i+10)));
m_pRecordset->PutCollect("username",_variant_t("haiyan"));
m_pRecordset->PutCollect("old",_variant_t((long)71));
m_pRecordset->PutCollect("birthday",_variant_t("1930-3-15"));
}
m_pRecordset->Move(1,_variant_t((long)adBookmarkFirst));///从第一条记录往下移动一条记录,即移
动到第二条记录处
m_pRecordset->PutCollect(_variant_t("old"),_variant_t((long)45));///修改其年龄
m_pRecordset->Update();///保存到库中
在这说明一下:
在我的一个.NET数据库连接程序中,出现一个问题,每次初始化打开数据集时程序报错说"数据库打开错误,无效指针",让我郁闷好几个小时,后来发现,当我在创建数据库连接对象前加入函数CoInitialize(NULL)后,错误解决,源码如下:
CoInitialize(NULL);
hr=m_pConnection.CreateInstance(_uuidof(Connection));
MSDC说明如下:
You need to initialize the COM library on anapartment before you call any of the
library functions except CoGetMalloc,to get apointer to the standard allocator,
and the memory allocation functions
(转)
为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtrm_pRecordset;
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
(1)利用Connection对象的Execute方法执行SQL命令
Execute方法的原型如下所示:
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT *RecordsAffected, long Options ) 其中CommandText是命令字串,通常是SQL命令。参数RecordsAffected是操作完成后所影响的行数, 参数Options表示CommandText中内容的类型,Options可以取如下值之一:
adCmdText:表明CommandText是文本命令
adCmdTable:表明CommandText是一个表名
adCmdProc:表明CommandText是一个存储过程
adCmdUnknown:未知
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 _variant_t RecordsAffected;
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:×××ID,字符串username,×××old,日期型birthday
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,oldINTEGER,birthday DATETIME)",&RecordsAffected,adCmdText);
///往表格里面添加记录
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday)valueS (1, nullnullnullnullnullnullnullnullWashingtonnullnullnullnullnullnullnullnull,25,nullnullnullnullnullnullnullnull1970/1/1nullnullnullnullnullnullnullnull)",&RecordsAffected,adCmdText);
///将所有记录old字段的值加一
m_pConnection->Execute("UPDATE users SET old =old+1",&RecordsAffected,adCmdText);
///执行SQL统计命令得到包含记录条数的记录集
m_pRecordset =m_pConnection->Execute("SELECT COUNT(*) FROMusers",&RecordsAffected,adCmdText);
_variant_t vIndex = (long)0;
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
m_pRecordset->Close();///关闭记录集
CString message;
message.Format("共有%d条记录",vCount.lVal);
AfxMessageBox(message);///显示当前记录条数
(2)利用Command对象来执行SQL命令
_CommandPtr m_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
_variant_t vNULL;
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
m_pRecordset =m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
ADO调用SQL Server存储过程
try{
if(m_pConnection==NULL) return;
m_pConnection->CursorLocation=adUseClient;//设置连接使用的光标类型
m_pRecordset.CreateInstance("ADODB.Recordset");
_CommandPtr m_pCommand;//初始化命令对象
m_pCommand.CreateInstance("ADODB.Command");//创建命令实例
m_pCommand->ActiveConnection=m_pConnection;//设置命令对象的连接
m_pCOmmand->CommandType=adCmdStoredProc;//设置命令对象处理的类型,在此为处理存储过程
m_pCommand->CommandText=_bstr_t(_T("GetEmployeeByName"));//其中GetEmployeeByName是存储过程的名称
m_pCommand->Parameters->Refresh();//刷新命令参数值
m_pCommand->Parameters->Item[_variant_t(_bstr_t("@EmployeeID"))]->Value=_variant_t(short(atoi(m_ID)));
//设置字段EmployeeID的值为@EmployeeID
m_pRecordset=m_pCommand->Execute(NULL,NULL,adCmdStoredProc)://执行存储过程
int iResult=-1;
_variant_t vResult;
vResult=m_pCommand->Parameters->GetItem(short(2))->Value;//获取返回值
iResult=vResult.intVal;//将返回值转换为int类型
CString log;
log.Format("调用存储过程,共查询到%d条记录",iResult);
if(m_pRecordset->RecordCount<=0){
m_pRecordset->Close();
m_pRecordset=NULL
m_pCommand.Detach();//释放命令对象
return;
}
else{}
}catch(_com_error e){
}