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

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

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

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

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

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

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

不含任何错误处理和异常处理,仅写关键代码。

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

用于测试的数据库

testdb

用于测试的登录名和密码

testdev

123456

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

1 [oledb]
2 ; Everything after this line is an OLE DB initstring
3 Provider=SQLOLEDB.1;Password=123456;Persist Security Info=True;User ID=testdev;Initial Catalog=testdb;Data Source=THBYTWO-PC-TEST\SQLEXPRESS

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

用于测试的表

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

用于测试的存储过程

1 CREATE PROC proc_testproc @id INT, @val INT
2 AS 
3     INSERT    INTO dbo.testtable
4             ( id, val )
5     VALUES    ( @id, -- id - int
6               @val  -- val - int
7               )

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

 简单的仅使用 连接对象 进行 连接和插入 操作。

 1     CoInitialize(NULL);
 2 
 3     _ConnectionPtr pConnection;
 4     pConnection.CreateInstance(TEXT("ADODB.Connection"));
 5 
 6     pConnection->ConnectionString=TEXT("File Name=sqlserver_ed.udl");
 7     pConnection->CommandTimeout=10;
 8     pConnection->CursorLocation=adUseClient;
 9     pConnection->Mode=adModeUnknown;
10     pConnection->Open(TEXT(""),TEXT(""),TEXT(""),adConnectUnspecified);
11 
12     CString strInsert;
13     strInsert.Format(TEXT("Insert into testtable values(%d,%d)"),5,6);
14 
15     pConnection->Execute(_bstr_t(strInsert),NULL,adCmdText);
16 
17     pConnection->Close(); 
18     pConnection.Release(); 
19 
20     CoUninitialize();

使用带参数的存储过程进行同样的插入操作

 1     int nID=2;
 2     int nVal=3;
 3 
 4     CoInitialize(NULL);
 5 
 6     _ConnectionPtr pConnection;
 7     pConnection.CreateInstance(TEXT("ADODB.Connection"));
 8     pConnection->ConnectionString=TEXT("File Name=sqlserver_ed.udl");
 9     pConnection->CommandTimeout=10;
10     pConnection->CursorLocation=adUseClient;
11     pConnection->Mode=adModeUnknown;
12     pConnection->Open(TEXT(""),TEXT(""),TEXT(""),adConnectUnspecified);
13 
14     _CommandPtr pCmd;
15     pCmd.CreateInstance(TEXT("ADODB.Command"));
16     pCmd->ActiveConnection=pConnection;    
17     pCmd->CommandText=_bstr_t(TEXT("proc_testproc"));
18     pCmd->CommandType=adCmdStoredProc;
19 
20     _ParameterPtr pParam1;
21     pParam1.CreateInstance(TEXT("ADODB.Parameter"));
22     pParam1=pCmd->CreateParameter(TEXT("id"),adInteger,adParamInput,sizeof(int));
23     pParam1->Value=_variant_t(nID);
24     pCmd->Parameters->Append(pParam1);
25 
26     _ParameterPtr pParam2;
27     pParam2.CreateInstance(TEXT("ADODB.Parameter"));
28     pParam2=pCmd->CreateParameter(TEXT("val"),adInteger,adParamInput,sizeof(int));
29     pParam2->Value=_variant_t(nVal);
30     pCmd->Parameters->Append(pParam2);
31 
32     pCmd->Execute(NULL,NULL,adCmdStoredProc); 
33 
34     pCmd.Release();
35     pConnection->Close();
36     pConnection.Release();
37 
38     CoUninitialize();

 另外,对于命令的执行,如果想要获得执行完成后显示的“N 行受影响”,那么,可以从参数中获得。

例如:

1 BOOL bInsert=FALSE;
2 VARIANT vRecordsAffected;
3 vRecordsAffected.vt=VT_I4;
4 vRecordsAffected.lVal=0;
5 pRecordset=pCmd->Execute(&vRecordsAffected,NULL,adCmdStoredProc);
6 if (vRecordsAffected.lVal==1)
7 {
8     bInsert=TRUE;
9 }

================================时间与泪的教训===============================

1 登录名要有能够执行存储过程的权限。

一开始我的testdev只有读写权限。后来用sa试了下验证了我的推断。

通过管理工具添加:数据库-testdb-安全性-用户-testdev

属性-安全对象-搜索-特定对象     确定

对象类型-存储过程          确定

浏览                 选中 确定 确定

显式                 选中 授予 确定

脚本添加:

1 USE testdb
2 GRANT EXECUTE ON proc_testproc TO testdev

2 确保杀毒软件和防护软件的策略为允许。

我在第一次运行测试程序时选错了大COMODO安全套装的规则策略,导致了连接总是异常。

后来我关闭了沙箱和HIPS验证了这个推断。

 

另外,经过一天(虚词)的浪费时间,我觉得,在测试自己的代码之前,先用同样的参数在sqlcmd里跑一下,总是好的,毕竟有提示,尤其是在对自己的代码很有信心的时候。

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

上一张COMODO的图片做个纪念,毕竟第一次在这里倒下。

还好自己爬起来了。

 

 

 

 

 

 

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

另外,编译器可以保证提醒到大多数的错误,但是将要执行的存储过程却是以文本方式传入的。所以要细心检查书写。