使用ADO呼叫儲存過程 (轉)

worldblog發表於2007-12-11
使用ADO呼叫儲存過程 (轉)[@more@]

使用ADO過程

在ADO中呼叫儲存過程一直是一個困擾大家的問題。其實,關於ADO呼叫儲存過程的
方法在很多書中都有講到,標準的做法無非是按照以下步驟進行:
1、生成並初始化一個_CommandPtr;
2、生成呼叫儲存過程需要的引數,這些引數都是_ParameterPtr物件;
3、按照順序將使用_CommandPtr的Append方法為儲存過程提供引數(包括輸入引數
和輸出引數);
4、為_CommandPtr物件指定需要使用的ADO連線;
5、使用_CommandPtr的Execute方法呼叫儲存過程;
6、從結果中獲取返回引數的值(如果有的話)。


具體的過程在此我不詳細描述,我想看看本文附帶的程式碼就應該很明白了。


在這裡我想就我使用ADO呼叫儲存過程時的一些體會說明一下。


1、關於CreateParameter


該函式的原型為:CreateParameter (Name, Type, Direction, Size, Value)


其中Name是引數的名稱,可以指定也可以不指定;
Type是一個DataTypeEnum值,指定引數的類別,取值有adInteger(整型)、adChar(字元/字串型)等;
Direction是一個ParameterDirectionEnum值,其取值為adParamInput、adParamInputOutput、
adParamOutput、adParamReturnValue、adParamUnknown;
Size是一個Long型別的值,指示該引數值以位元組計算的最大長度,例如對int型,該值可以取為sizeof(int),
對Long型,該值可以取為sizeof(long),對字串型,可以使用該字串的長度;
Value是一個variant型別的值,是該引數的取值。


在這裡需要注意的是,Type引數、Direction引數以及Size引數一定要和儲存過程定義時的引數相吻合,


例如,如果有下面一個儲存過程
  CREATE  PROCEDURE SMS_Proc_Handle_All
  (@UserID Integer,
  @SourAddr Varchar(15),
  @DestAddr varchar(5000),
  @AvValue Single output,
  @ReturnInfo varchar(100) output
  )
則Type引數的取值依次為adInteger、adChar、adChar、adSingle,adChar;
Direction引數的取值依次為adParameterIn、adParameterIn、adParameterIn、adParameterOut、adParameterOut;
對於輸入引數,Size的值可以根據實際數值來定,對於輸出引數,最好是根據定義確定(上例中ReturnInfo引數的
Size值可以取為100)。


2,關於獲取Output的引數


獲取ourput引數是大家最關注的問題,同時也是最“難”的問題,因為按照書本上的寫法,經常獲得不了
Output引數,其實這個問題很容易解決:在呼叫_CommandPtr的Execute方法時,寫成
cmmd->Execute(NULL, NULL, adCmdStoredProc);
而不要寫成
RecordsetPtr rec = cmmd->Execute(NULL, NULL, adCmdStoredProc);
也就是說,不取返回值(我不知道這是為什麼,但是相信我,事情就是這樣)。
這句完後,使用
cmmd->Parameters->GetItem("XXXXXX")->GetValue();
  ^^^^^^^
  輸出引數的名稱
就可以獲得輸出引數的值了。


以下是一個透過ADO呼叫儲存過程的部分程式碼:


  _CommandPtr cmmd;
  HRESULT hr = cmmd.CreateInstance(__uuidof(Command));
  if(FAILED(hr))
  {
   AfxMessageBox("NeDatabase()中建立_CommandPtr物件失敗");
   return 0;
  }
  _ParameterPtr param;
  param = cmmd->CreateParameter(""/*NetType*/,adTinyInt, adParamInput,
   sizeof(BYTE),(BYTE)(m_nNetType+1));
  cmmd->Parameters->Append(param);
  param = cmmd->CreateParameter(""/*Name*/,adVarChar, adParamInput,
   m_strName.GetLength()+1, _variant_t(m_strName));
  cmmd->Parameters->Append(param);
  param = cmmd->CreateParameter(""/*Desp*/,adVarChar, adParamInput,
   m_strDesp.GetLength()+1, _variant_t(m_strDesp));
  cmmd->Parameters->Append(param);
  param = cmmd->CreateParameter("NewNetID"/*NetID*/,adInteger, adParamOutput,
   sizeof(long), (long)m_nNewNetID);//返回引數,返回新建的的ID
  cmmd->Parameters->Append(param);
  cmmd->CommandText=_bstr_t("GSDT_NewNet");//儲存過程的名稱
  cmmd->ActiveConnection = m_pConPtr;//需要使用的ADO連線
  cmmd->CommandType=adCmdStoredProc;
  //注意下面的一行程式碼,如果你寫成這樣,就獲得不了返回引數的值
 //_RecordsetPtr rec = cmmd->Execute(NULL, NULL, adCmdStoredProc);
  //我不知道這是為什麼,但事實就是這樣:)
  cmmd->Execute(NULL, NULL, adCmdStoredProc);
  m_nNewNetID=(long)cmmd->Parameters->GetItem("NewNetID")->GetValue();//透過引數返回值
  cmmd.Detach();


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-991253/,如需轉載,請註明出處,否則將追究法律責任。

相關文章