==================================声明==================================

本文原创,转载在正文中显要的注明作者和出处,并保证文章的完整性。

未经作者同意请勿修改(包括本声明),保留法律追究的权利。

未经作者同意请勿用于出版、印刷或学术引用。

本文不定期修正完善,为保证内容正确,建议移步原文处阅读。

本文链接:http://www.cnblogs.com/wlsandwho/p/4361950.html

=======================================================================

文中使用到的TESTHR函数,并非本人所写,摘自中文版chm格式的《microsoft ado 2.5 程序员参考》。

1 inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);}

=======================================================================

错误处理跟优雅退出肯定写的不好,凑合下吧。

=======================================================================

本例的目的/效果:以事务的方式从表testtable中删除并插入到testtable2中。

=======================================================================

用于测试的数据库

testdb

用于测试的登录名和密码

testdev

123456

用于测试的sqlserver_ed.udl文件内容

1 [oledb]
2 ; Everything after this line is an OLE DB initstring
3 Provider=SQLOLEDB.1;Password=HTSQL;Persist Security Info=True;User ID=sa;Initial Catalog=testdb;Data Source=192.168.0.14\SQLEXPRESS

用于测试的表

CREATE TABLE  testtable(
    id   int NULL,
    val int NULL
)

CREATE TABLE  testtable2(
    id   int NULL,
    val int NULL
)

表中初始数据

testtable中

10086,10010

testtable2中

用于测试的存储过程

(不要吐槽我为什么用存储过程了,我就是练一下,简单功能用普通的参数化语句就行了。)

(PS:据说数据库会编译存储过程,这样下次运行会更快。我不是专业数据库人员,详细的还是看手册吧。)

 1 CREATE PROC proc_DeleteSomething @id INT, @val INT
 2 AS 
 3     BEGIN
 4         DELETE    FROM dbo.testtable
 5         WHERE    id = @id AND val=@val
 6     END
 7 
 8 GO
 9 
10 CREATE PROC proc_InsertSomething @id INT, @val INT
11 AS 
12     BEGIN
13         INSERT INTO dbo.testtable2
14                 ( id, val )
15         VALUES    ( @id, -- id - int
16                   @val  -- val - int
17                   )
18     END
19 
20 GO

记得要给用户授予执行权限。

=======================================================================

VC++测试代码

 1     if (FAILED(::CoInitialize(NULL)))
 2     {
 3         MessageBox(TEXT("初始化失败"));
 4 
 5         return;
 6     }
 7 
 8     int nID=10086;
 9     int nVal=10010;
10 
11     _ConnectionPtr    pConn;
12     _CommandPtr       pCmd;
13     _ParameterPtr     pParam1;
14     _ParameterPtr     pParam2;
15 
16     int nTransLevel=0;
17 
18     HRESULT  hr = S_OK;
19 
20     try
21     {
22         TESTHR(pConn.CreateInstance(TEXT("ADODB.Connection")));
23         
24         pConn->ConnectionString=TEXT("File Name=sqlserver_ed.udl");
25         pConn->CommandTimeout=10;
26         pConn->CursorLocation=adUseClient;
27         pConn->Mode=adModeUnknown;
28         pConn->Open(TEXT(""),TEXT(""),TEXT(""),adConnectUnspecified);
29 
30         TESTHR(pCmd.CreateInstance(TEXT("ADODB.Command")));
31 
32         pCmd->ActiveConnection=pConn;
33         pCmd->CommandType=adCmdStoredProc;
34         
35         TESTHR(pParam1.CreateInstance(TEXT("ADODB.Parameter")));
36 
37         pParam1=pCmd->CreateParameter(TEXT("id"),adInteger,adParamInput,sizeof(int));
38         pParam1->Value=_variant_t(nID);
39         pCmd->Parameters->Append(pParam1);
40 
41         TESTHR(pParam2.CreateInstance(TEXT("ADODB.Parameter")));
42 
43         pParam2=pCmd->CreateParameter(TEXT("val"),adInteger,adParamInput,sizeof(int));
44         pParam2->Value=_variant_t(nVal);
45         pCmd->Parameters->Append(pParam2);
46 
47         nTransLevel=pConn->BeginTrans();
48             pCmd->CommandText=_bstr_t(TEXT("proc_DeleteSomething"));
49             pCmd->Execute(NULL,NULL,adCmdStoredProc);
50             
51             pCmd->CommandText=_bstr_t(TEXT("proc_InsertSomething"));
52             pCmd->Execute(NULL,NULL,adCmdStoredProc);
53         pConn->CommitTrans();
54     }
55     catch (_com_error &e)
56     {
57         if (nTransLevel==1)
58         {
59             pConn->RollbackTrans();
60         }
61     }
62     catch (CException* e)
63     {
64     }
65 
66     CoUninitialize();

 

在代码中制造错误的时候,可以将第二个存储过程名写错。

 

 

 

=================================写给自己=================================

软件开发这种实践性很强的东西,不自己亲手实验,又怎能解除困惑?