文中使用到的TESTHR函数,并非本人所写,摘自中文版chm格式的《microsoft ado 2.5 程序员参考》。
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);}
=======================================================================
错误处理跟优雅退出肯定写的不好,凑合下吧。
=======================================================================
本例的目的/效果:以事务的方式从表testtable中删除并插入到testtable2中。
=======================================================================
用于测试的数据库
testdb
用于测试的登录名和密码
testdev
123456
用于测试的sqlserver_ed.udl文件内容
[oledb] ;Everything after this line is an OLE DB initstring Provider=SQLOLEDB.1;Password=HTSQL;Persist Security Info=True;User ID=sa;Initial Catalog=testdb;Data Source=192.168.0.14\SQLEXPRESS
用于测试的数据库表的sql脚本
CREATE TABLE testtable( id int NULL, val int NULL ) CREATE TABLE testtable2( id int NULL, val int NULL )
表中初始数据
testtable中
10086,10010
testtable2中
无
用于测试的存储过程
(不要吐槽我为什么用存储过程了,我就是练一下,简单功能用普通的参数化语句就行了。)
(PS:据说数据库会编译存储过程,这样下次运行会更快。我不是专业数据库人员,详细的还是看手册吧。)
CREATE PROC proc_DeleteSomething @id INT, @val INT AS BEGIN DELETE FROM dbo.testtable WHERE id = @id AND val=@val END GO CREATE PROC proc_InsertSomething @id INT, @val INT AS BEGIN INSERT INTO dbo.testtable2 ( id, val ) VALUES ( @id, -- id - int @val -- val - int ) END GO
记得要给用户授予执行权限。
=======================================================================
VC++测试代码
if (FAILED(::CoInitialize(NULL)))
{
MessageBox(TEXT("初始化失败"));
return;
}
int nID=10086;
int nVal=10010;
_ConnectionPtr pConn;
_CommandPtr pCmd;
_ParameterPtr pParam1;
_ParameterPtr pParam2;
int nTransLevel=0;
HRESULT hr = S_OK;
try
{
TESTHR(pConn.CreateInstance(TEXT("ADODB.Connection")));
pConn->ConnectionString=TEXT("File Name=sqlserver_ed.udl");
pConn->CommandTimeout=10;
pConn->CursorLocation=adUseClient;
pConn->Mode=adModeUnknown;
pConn->Open(TEXT(""),TEXT(""),TEXT(""),adConnectUnspecified);
TESTHR(pCmd.CreateInstance(TEXT("ADODB.Command")));
pCmd->ActiveConnection=pConn;
pCmd->CommandType=adCmdStoredProc;
TESTHR(pParam1.CreateInstance(TEXT("ADODB.Parameter")));
pParam1=pCmd->CreateParameter(TEXT("id"),adInteger,adParamInput,sizeof(int));
pParam1->Value=_variant_t(nID);
pCmd->Parameters->Append(pParam1);
TESTHR(pParam2.CreateInstance(TEXT("ADODB.Parameter")));
pParam2=pCmd->CreateParameter(TEXT("val"),adInteger,adParamInput,sizeof(int));
pParam2->Value=_variant_t(nVal);
pCmd->Parameters->Append(pParam2);
nTransLevel=pConn->BeginTrans();
pCmd->CommandText=_bstr_t(TEXT("proc_DeleteSomething"));
pCmd->Execute(NULL,NULL,adCmdStoredProc);
pCmd->CommandText=_bstr_t(TEXT("proc_InsertSomething"));
pCmd->Execute(NULL,NULL,adCmdStoredProc);
pConn->CommitTrans();
}
catch (_com_error &e)
{
if (nTransLevel==1)
{
pConn->RollbackTrans();
}
}
catch (CException* e)
{
}
CoUninitialize();在代码中制造错误的时候,可以将第二个存储过程名写错。
=================================后记=================================
软件开发这种实践性很强的东西,不自己亲手实验,又怎能解除困惑......