2. 為了使我們的呼叫儲存過程的例子有更多的通用性,我建了有輸入引數,有輸出引數,有乙個返回記錄集,有乙個返回值的儲存過程,如下
create procedure sp_1 (
@pin1 int ,
@pin2 char(10),
@pout1 int output,
@pout2 char(10) output
)as
begin
declare @retval int
select @pout1 = @pin1 + 100
select @pout2 = left( ltrim(rtrim(@pin2)) + '123' , 10)
select num,name,date
from table1
select @retval = 1236
return @retval
end對於這個sp來說,他這些個引數是
@return_value(int ,返回值)
@pin1 ( int ,輸入 )
@pin2 ( char(10) ,輸入 )
@pout1 (int ,輸入/輸出)
@pout1 ( char(10) , 輸入/輸出)
@return_value是第0個引數,@pin1是第1個,依此類推
以上資訊可以在sql 的查詢分析器中看到,注意,這些引數的順序很重要
3.呼叫的前期準備
這就不多說了,什麼import 庫阿,建立連線阿,什麼的,不多說了,
這些在vc中使用ado進行資料庫開發的一些資料的整理
中有了闡述
假定連線是pconn
注意,這裡要把pconn設定成aduseclient型
pconn->cursorlocation =aduseclient;
下面我要貼具體的**了,為了精簡所貼的**,我把所有的捕獲異常都沒貼出來(try catch)
4.使用refresh的方法來呼叫
先定義一些變數
_commandptr pcmd = null;
_recordsetptr precordset = null;
初試化他們,
pcmd.createinstance(__uuidof(command));
precordset.createinstance(_uuidof(recordset));
pcmd->activeconnection = pconn;
pcmd->commandtype = adcmdstoredproc;
pcmd->commandtext=_bstr_t(_t("sp_1")); //sp name
然後給那些input引數賦值
pcmd->parameters->refresh();
pcmd->parameters->item[_variant_t(_bstr_t("@pin1") )]->value=_variant_t(3);
pcmd->parameters->item[_variant_t(_bstr_t("@pin2") )]->value=_variant_t("dd");
這個refresh一定要有,
調spprecordset = pcmd->execute(null,null,adcmdstoredproc);
int retval = -1;
_variant_t vretval ;
//getretval
vretval = pcmd->parameters->getitem(short(0))->value;
retval = vretval.lval;
info.format(_t("the return value is : %d"),retval);
messagebox(info);
//output1
vretval = pcmd->parameters->getitem(short(3))->value;
retval = vretval.lval;
info.format(_t("the output1 value is : %d"),retval);
messagebox(info);
//@pout2
vretval = pcmd->parameters->getitem(short(4))->value;
info= (lpctstr)_bstr_t(vretval);
cstring info1;
info1.format(_t("the output2 value is : %s"),info);
messagebox(info1);
//取記錄集裡面的內容
if (precordset->adobof && precordset->adoeof)
pcmd.detach();
return;
} precordset->movefirst();
for(;!precordset->adoeof;precordset->movenext())
if(precordset != null && precordset->state)
最後pcmd.detach();
在這裡,有一點要注意的是
vretval = pcmd->parameters->getitem(short(4))->value;
這裡的4,就是哪個output引數的index,就是我在2中說的引數的順序
這裡使用了refresh,這是乙個很重要的函式,我將在下面介紹一下它,我要先貼出另一種,不使用refresh的辦法,
5 .使用非refresh的方法來呼叫
先定義變數
_commandptr pcmd = null;
_recordsetptr precordset = null;
_parameterptr retparam = null;
_parameterptr inparam1 = null;
_parameterptr inparam2 = null;
_parameterptr outparam1 = null;
_parameterptr outparam2 = null;
初試化pcmd.createinstance(__uuidof(command));
precordset.createinstance(_uuidof(recordset));
retparam.createinstance(__uuidof(parameter));
//其他的parameterptr 也初試化
pcmd->activeconnection = pconn;
pcmd->commandtype = adcmdstoredproc;
pcmd->commandtext=_bstr_t(_t("sp_1")); //sp name
inparam1 = pcmd ->createparameter(_bstr_t("inparam1"),
adinteger,
adparaminput,
sizeof(int));
inparam1->value = _variant_t(3);
inparam2 = pcmd ->createparameter(_bstr_t("inparam2"),
adchar,
adparaminput,
10);
inparam2->value = _variant_t(_t("dd1"));
這裡不用refresh的辦法,是用parameter來,這裡要注意的是,這個add的順序要和引數的index順序要一致
下面就是呼叫了
precordset = pcmd->execute(null,null,adcmdstoredproc);
然後取那些return值阿,output值阿什麼的
這裡有乙個區別,就是用這種辦法
可以有三種辦法來取這些返回值和output引數
vretval = pcmd->parameters->getitem(_bstr_t("return"))->value;
vretval = pcmd->parameters->getitem(short(0))->value;
vretval = retparam->value;
都是一樣的
6. 關於refresh
關於這個函式,作用是
command 物件去重新索取要操作的儲存過程所有有關引數的資訊,並且清空在refresh之前獲取的引數資訊。
所以一但呼叫它以後,就可以獲取sp的那些資訊,那些引數的資訊,可以通過pcmd->parameters->item[_variant_t(_bstr_t("@pin1") )]->value=_variant_t(3); 這樣的方式來設定引數
如果要使用parameter的辦法的話,就不要用refresh了,事實上,如果先把這些引數的值設定好了,如 inparam2->value = _variant_t(_t("dd1"));,一旦refresh後,這些引數就沒有意義了。
7.關於pconn->cursorlocation =aduseclient;
設定這個東西,如果不設定游標為aduseclient,那麼我在取return和output引數的時候,必須在我把記錄集關閉以後才能取,就是說,必須先取記錄集,然後關閉它,最後再取return和output引數,如果我在關閉記錄集之前就取return和output的值,那麼就不能取到正確的值,設成aduseclient就ok了,
另外有一點就是,execute 方法返回的游標繼承該設定。recordset 將自動從與之關聯的連線中繼承該設定。我把pconn設成aduseclient,那麼最後,我的記錄集也是aduseclient的了
ADO呼叫儲存過程
usingsystem usingsystem.collections.generic usingsystem.componentmodel usingsystem.data usingsystem.drawing usingsystem.linq usingsystem.text usingsys...
ADO呼叫儲存過程例項講解
1 直接有返回值的儲存過程 public string getprojectcode 或者直接以sql的形式呼叫 public string getprojectcode 呼叫無引數的儲存過程,直接呼叫儲存過程的返回值 public static datatable pro categorys pr...
ADO呼叫分頁查詢儲存過程
一 分頁儲存過程 使用儲存過程編寫乙個分頁查詢 set nocount off 關閉sqlserver訊息 set nocount on 開啟sqlserver訊息 gocreate proc usp getmystudentsdatabypage 輸入引數 pagesize int 7,每頁記錄條...