MFC数据库连接整理.docx
《MFC数据库连接整理.docx》由会员分享,可在线阅读,更多相关《MFC数据库连接整理.docx(17页珍藏版)》请在冰豆网上搜索。
MFC数据库连接整理
>1.VC连接SQLServer数据库时步骤
-----------------------------------------------------
(1)初始化COM库,引入ADO库定义文件。
在MFC中可以用AfxOleInit();非MFC环境中用:
CoInitialize(NULL);CoUnInitialize();
(2)用Connection对象连接数据库
(3)利用建立好的连接,通过Connection、Command对象执行SQL命令,或利用Recordset对象取得结果记录集进行查询、处理。
(4)使用完毕后关闭连接释放对象。
>2.连接数据库的方式
-----------------------------------------------------
OLEDB 是一种基于组件对象的数据库连接方式.
ADO 是建立在OLEDB基础之上的一种简单快速的OLEDB连接方式.
ODBC 各数据库厂商基于Microsoft开发给他们的数据库公共接口而开发的连接方式.
DAO 是微软开发的更简单的数据连接方式, 早期使用得比较多.
>3.ODBC链接
-----------------------------------------------------
适合数据库类型 链接方式
access"Driver={microsoftaccessdriver(*.mdb)};dbq=*.mdb;uid=admin;pwd=pass;"
dBase"Driver={microsoftdbasedriver(*.dbf)};driverid=277;dbq=------------;"
Oracle"Driver={microsoftodbcfororacle};server=oraclesever.world;uid=admin;pwd=pass;"
MSSQLserver"Driver={sqlserver};server=servername;database=dbname;uid=sa;pwd=pass;"
MStext"Driver={microsofttextdriver(*.txt;*.csv)};dbq=-----;extensions=asc,csv,tab,txt;PersistSecurityInfo=false;"
VisualFoxpro"Driver={microsoftVisualFoxprodriver};sourcetype=DBC;sourceDB=*.dbc;Exclusive=No;"
MySQL"Driver={mysql};database=yourdatabase;uid=username;pwd=yourpassword;option=16386;"
>4.OLEDB链接
-----------------------------------------------------
适合的数据库类型 链接方式
access"Provider=microsoft.jet.oledb.4.0;datasource=your_database_path;userid=admin;password=pass;"
Oracle"Provider=OraOLEDB.Oracle;datasource=dbname;userid=admin;password=pass;"
MSSQLServer"Provider=SQLOLEDB;datasource=machinename;initialcatalog=dbname;userid=sa;password=pass;"
>5. 基本数据库操作
-----------------------------------------------------
添加
a)、调用m_pRecordset->AddNew();
b)、调用m_pRecordset->PutCollect();给每个字段赋值
c)、调用m_pRecordset->Update();确认
删除
a)、把记录指针移动到要删除的记录上,然后调用Delete(adAffectCurrent)
try
{
// 假设删除第二条记录
m_pRecordset->MoveFirst();
m_pRecordset->Move
(1);
m_pRecordset->Delete(adAffectCurrent);// 参数adAffectCurrent为删除当前记录
m_pRecordset->Update();
}
catch(_com_error*e)
{
AfxMessageBox(e->ErrorMessage());
}
>6. 直接执行SQL语句实现
-----------------------------------------------------
除了要用到结果集其余的大部分功能都可以直接用SQL语言实现
(1)、用_CommandPtr和_RecordsetPtr配合
_CommandPtrm_pCommand;
m_pCommand.CreateInstance(__uuidof(Command));// 将库连接赋于它
m_pCommand->ActiveConnection=m_pConnection;
//SQL语句
m_pCommand->CommandText="SELECT*FROMDemoTable";
// 执行SQL语句,返回记录集
m_pRecordset=m_pCommand->Execute(NULL,NULL,adCmdText);
(2)、直接用_ConnectionPtr执行SQL语句
_RecordsetPtrConnection15:
:
Execute(_bstr_tCommandText,VARIANT*RecordsAffected,longOptions)
其中CommandText是命令字串,通常是SQL命令。
参数RecordsAffected是操作完成后所影响的行数,
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
adCmdText:
表明CommandText是文本命令
adCmdTable:
表明CommandText是一个表名
adCmdProc:
表明CommandText是一个存储过程
adCmdUnknown:
未知
例子:
_variant_tRecordsAffected;
m_pConnection->Execute("UPDATEusersSETold=old+1",&RecordsAffected,adCmdText);
>7. 调用存储过程
-----------------------------------------------------
(1)利用_CommandPtr
_CommandPtrm_pCommand;
m_pCommand.CreateInstance(__uuidof(Command));
m_pCommand->ActiveConnection=m_pConnection;// 将库连接赋于它
m_pCommand->CommandText="Demo";
m_pCommand->Execute(NULL,NULL,adCmdStoredProc);
(2)直接用_ConnectionPtr直接调用(见4.
(2))
6.遍历数据库中的所有表名_ConnectionPtrm_pConnect;
_RecordsetPtrpSet;
HRESULThr;
try
{
hr=m_pConnect.CreateInstance("ADODB.Connection");
if(SUCCEEDED(hr))
{
CStringdd;
dd.Format("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=%s",file);
hr=m_pConnect->Open((_bstr_t)dd,"","",adModeUnknown);
pSet=m_pConnect->OpenSchema(adSchemaTables);
while(!
(pSet->adoEOF))
{
//获取表格
_bstr_ttable_name=pSet->Fields->GetItem("TABLE_NAME")->Value;
_bstr_ttable_type=pSet->Fields->GetItem("TABLE_TYPE")->Value;//获取表格类型
//过滤一下,只输出表格名称,其他的省略
if(strcmp(((LPCSTR)table_type),"TABLE")==0){
CStringtt;
tt.Format("%s",(LPCSTR)table_name);
AfxMessageBox(tt);
}
pSet->MoveNext();
}
pSet->Close();
}
m_pConnect->Close();
}catch(_com_errore)///捕捉异常
{
CStringerrormessage;
errormessage.Format("连接数据库失败!
rn错误信息:
%s",e.ErrorMessage());
AfxMessageBox(errormessage);
return-1;
}
>8. 遍历一个表中的所有字段
-----------------------------------------------------
Field*field=NULL;
HRESULThr;
Fields*fields=NULL;
hr=m_pRecordset->get_Fields(&fields);//得到记录集的字段集和
if(SUCCEEDED(hr))
fields->get_Count(&ColCount);
//得到记录集的字段集合中的字段的总个数
for(i=0;iItem[i]->get_Name(&bstrColName);//得到记录集//中的字段名
strColName=bstrColName;
nameField=strColName;
m_FieldsList.AddString(nameField);
}
if(SUCCEEDED(hr))
fields->Release();//释放指针
>9. 几个特殊字段
-----------------------------------------------------
1、_variant_t
(1)、一般传给这3个指针的值都不是MFC直接支持的数据类型,而要用_variant_t转换一下
_variant_t(XX)可以把大多数类型的变量转换成适合的类型传入:
(2)、_variant_tvar;_variant_t->long:
(long)var;
_variant_t->CString:
CStringstrValue=(LPCSTR)_bstr_t(var);
CString->_variant_t:
_variant_t(strSql);
2、BSTR宽字符串与CString相互转换
BSTRbstr;
CStringstrSql;
CString->BSTR:
bstr=strSql.AllocSysString();
BSTR->CString:
strSql=(LPCSTR)bstr;
3、_bstr_t与CString相互转换
_bstr_tbstr;
CStringstrSql;
CString->_bstr_t:
bstr=(_bstr_t)strSql;
_bstr_t->CString:
strSql=(LPCSTR)bstr;
4、关于时间
Access:
表示时间的字符串#2004-4-5#
Sql:
表示时间的字符串''2004-4-5''
DateField(时间字段)select*frommy_tablewhereDateField>#2004-4-10#
>10.Connection对象的Open方法
-----------------------------------------------------
原型HRESULTConnection15:
:
Open(_bstr_tConnectionString,_bstr_tUserID,_bstr_tPassword,longOptions)
ConnectionString为连接字串,UserID是用户名,Password是登陆密码,Options是连接选项,用于指定Connection对象对数据的更新许可权,
Options可以是如下几个常量:
adModeUnknown:
缺省。
当前的许可权未设置
adModeRead:
只读
adModeWrite:
只写
adModeReadWrite:
可以读写
adModeShareDenyRead:
阻止其它Connection对象以读权限打开连接
adModeShareDenyWrite:
阻止其它Connection对象以写权限打开连接
adModeShareExclusive:
阻止其它Connection对象以读写权限打开连接
adModeShareDenyNone:
阻止其它Connection对象以任何权限打开连接
>11.Connection对象除Open方法中常用的连接方式
-----------------------------------------------------
(1)通过JET数据库引擎对ACCESS2000数据库的连接
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=C:
\\test.mdb","","",adModeUnknown);
(2)通过DSN数据源对任何支持ODBC的数据库进行连接:
m_pConnection->Open("DataSource=adotest;UID=sa;PWD=;","","",adModeUnknown);
(3)不通过DSN对SQLSERVER数据库进行连接:
m_pConnection->Open("driver={SQLServer};Server=127.0.0.1;DATABASE=vckbase;UID=sa;PWD=139","","",adModeUnknown);
其中Server是SQL服务器的名称,DATABASE是库的名称
>12.Connection对象中两个有用的属性ConnectionTimeOut与State
-----------------------------------------------------
ConnectionTimeOut用来设置连接的超时时间,需要在Open之前调用,例如:
m_pConnection->ConnectionTimeout=5;///设置超时时间为5秒
m_pConnection->Open("DataSource=adotest;","","",adModeUnknown);
State属性指明当前Connection对象的状态,0表示关闭,1表示已经打开,我们可以通过读取这个属性来作相应的处理,例如:
if(m_pConnection->State)
m_pConnection->Close();///如果已经打开了连接则关闭它
>13.利用Connection对象的Execute方法
-----------------------------------------------------
_RecordsetPtrConnection15:
:
Execute(_bstr_tCommandText,VARIANT*RecordsAffected,longOptions)
其中CommandText是命令字串,通常是SQL命令。
参数RecordsAffected是操作完成后所影响的行数,
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
adCmdText:
表明CommandText是文本命令
adCmdTable:
表明CommandText是一个表名
adCmdProc:
表明CommandText是一个存储过程
adCmdUnknown:
未知
>14.Execute执行及执行之后的结果
-----------------------------------------------------
_variant_tRecordsAffected;
///执行SQL命令:
CREATETABLE创建表格users,users包含四个字段:
整形ID,字符串username,整形old,日期型birthday
m_pConnection->Execute("CREATETABLEusers(IDINTEGER,usernameTEXT,oldINTEGER,birthdayDATETIME)",&RecordsAffected,adCmdText);
///往表格里面添加记录
m_pConnection->Execute("INSERTINTOusers(ID,username,old,birthday)VALUES(1,'Washington',25,'1970/1/1')",&RecordsAffected,adCmdText);
///将所有记录old字段的值加一
m_pConnection->Execute("UPDATEusersSETold=old+1",&RecordsAffected,adCmdText);
///执行SQL统计命令得到包含记录条数的记录集
m_pRecordset=m_pConnection->Execute("SELECTCOUNT(*)FROMusers",&RecordsAffected,adCmdText);
_variant_tvIndex=(long)0;
_variant_tvCount=m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
m_pRecordset->Close();///关闭记录集
CStringmessage;
message.Format("共有%d条记录",vCount.lVal);
AfxMessageBox(message);///显示当前记录条数
>15. 利用Command对象来执行SQL命令
-----------------------------------------------------
_CommandPtrm_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
_variant_tvNULL;
vNULL.vt=VT_ERROR;
vNULL.scode=DISP_E_PARAMNOTFOUND;///定义为无参数
m_pCommand->ActiveConnection=m_pConnection;///非常关键的一句,将建立的连接赋值给它
m_pCommand->CommandText="SELECT*FROMusers";///命令字串
m_pRecordset=m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。
下次我们将详细介绍。
>16. 直接用Recordset对象进行查询取得记录集
-----------------------------------------------------
m_pRecordset->Open("SELECT*FROMusers",_variant_t((IDispatch*)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
Open方法的原型:
HRESULTRecordset15:
:
Open(const_variant_t&Source,const_variant_t&ActiveConnection,enumCursorTypeEnumCursorType,enumLockTypeEnumLockType,longOptions)
其中:
①Source是数据查询字符串
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
③CursorType光标类型,它可以是以下值之一,这个枚举结构:
enumCursorTypeEnum
{
adOpenUnspecified=-1,///不作特别指定
adOpenForwardOnly=0,///前滚静态光标。
这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。
但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
adOpenKeyset=1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
adOpenDynamic=2,///动态光标。
所有数据库的操作都会立即在各用户记录集上反应出来。
adOpenStatic=3///静态光标。
它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
};
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
enumLockTypeEnum
{
adLockUnspecified=-1,///未指定
adLockReadOnly=1,///只读记录集
adLockPessimistic=2,悲观锁定方式。
数据在更新时锁定其它所有动作,这是最安全的锁定机制
adLockOptimistic=3,乐观锁定方式。
只有在你调用Update方法时才锁定记录。
在此之前仍然可以做数据的更新、插入、删除等动作
adLockBatchOptimistic=4,乐观分批更新。
编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
};
>17. 查看记录集中记录
------------------------------------