來自:http://blog.csdn.net/Willin/archive/2004/12/21/224027.aspx
在一個項目中,我需要用到存儲過程來訪問數(shù)據(jù),為了提供一個比較一致的接口以便調(diào)用,我沒有使用CreateParameter(),而是調(diào)用CommandPtr的Refresh()函數(shù)先從數(shù)據(jù)庫中查詢參數(shù).
_ConnectionPtr m_pConn;
m_pConn.CreateInstance(__uuidof(Connection));
m_pConn->Open("driver={SQL Server};server=127.0.0.1;DATABASE=pub;UID=sa;PWD=", "","",0);
_CommandPtr m_pCommand;
m_pCommand.CreateInstance(__uuidof(Command));
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance(__uuidof(Recordset));
m_pCommand->ActiveConnection = m_pConn;
m_pCommand->CommandText = "SP_XX";//存儲過程名
m_pCommand->PutCommandType(adCmdStoredProc);
m_pCommand->Parameters->Refresh();//從數(shù)據(jù)庫查詢參數(shù)信息
接下來就可以對每一個參數(shù)賦值了:
long cnt = m_pCommand->Parameters->GetCount();//取得參數(shù)的個數(shù)
for(long k=1;k<cnt;k++)
{//由于ADO中認(rèn)為返回值是第一個參數(shù),因此這里用k=1濾掉第一個參數(shù)
m_pCommand->Parameters->GetItem(k)->Value = XXX;//按存儲過程的參數(shù)順序給參數(shù)賦值
}
現(xiàn)在可以執(zhí)行這個存儲過程了
m_pRecordset = m_pCommand->Execute(0,0,adCmdStoredProc);
這個時候,如果接下來用
_variant_t ret_val = m_pCommand->Parameters->GetItem((long)0)->Value;
那么將得不到值
而如果像下面這樣調(diào)用的話就可以得到返回值了
m_pRecordset->Close();
_variant_t output_para = m_pCommand->Parameters->GetItem((long)0)->Value;
MS ADO.net給這一現(xiàn)象的回復(fù)是:
You
can think of a stored procedure as a function in your code. The
function doesn’t return a value until it has executed all of its code.
If the stored procedure returns results and you haven’t finished
processing these results, the stored procedure hasn’t really finished
executing. Until you’ve closed the DataReader, the return and output parameters of your Command won’t contain the values returned by your stored procedure.
也就是說Execute()函數(shù)應(yīng)該看成是直到m_pRecordset關(guān)掉以后才會正確返回.
關(guān)于輸出參數(shù)的處理也和這一樣,因為返回值本身就是當(dāng)成輸出參數(shù)來處理的.
通過這種方法,我們可以得到一個存儲過程的返回值和結(jié)果集,而且對于所有的存儲過程都可以一樣使用,不必為某個特定的存儲過程去寫代碼,具有一定的通用性.