OCI調用存儲過程

OCI調用存儲過程

最近的風控框架開發中,遇到一個場景,即程序需要調用Oracle中的存儲過程,但是目前的框架中並不支持,只支持調用組裝好的SQL語句,即基本的數據庫增刪改查操作,這樣就需要開發OCI調用存儲過程。

基於這個需求,開始網上找尋資料。由於使用到的是OCI接口,而該接口文檔只有英文版,而且很不全面,偏偏需要使用到的OCI調用存儲過程API程序例子沒有,所以只能從網上一些博客等找尋。經過不停的搜索,關鍵字換來換去的搜索,搜索引擎從百度,Google鏡像網站,最後到微軟的必應搜索,都使用到了,仍然沒有搜索到一個正確的完整的代碼示例。找到了一兩個類似的感覺可以使用的,編譯,運行發現都是不行的。驗證了那就話,中國的很多技術博客就是你抄我,我抄你。然後開始往一些國外的網站搜索,StackOverflow等等,都沒有搜索到完整的正確的示例,最後根據之前的OCI程序封裝,推測出調用存儲過程的類似寫法,把整體的調用函數寫完了,之後就是參數的問題了,參數比較多,使用起來特別複雜,需要知道每個參數的意義。經過不斷的編譯,運行,測試,最後將所有的參數調試正確運行完整。

最後的完整示例代碼如下,方便以後的開發人員使用。不用像我這樣發費這麼大精力去搜索和試驗。

int ora_procedure_execute(struct S_OracleContext*oractx, constchar*pszSQL,char*userid,char*exptype,char*conditionexp,char**resultof,int*errorcode,char**errormsg){

   OCIBind  * bidhp[6];

   sb2  sb2aInd[3];

   OCIStmt*stmthp=NULL;

   swordretcode = 0;

   sb4errcode = 0;

   *resultof= NULL;

   *errorcode=NULL;

   *errormsg= NULL;

   char *pszGBKSQL;

   //數據庫需要 GBK SQL語句。因此需要轉換字符集

   pszGBKSQL= UTF8ToGBK(pszSQL);

   if (!pszGBKSQL)

   {

      LogMessage("utf8 to gbk failed in ora_execute()");

      return -1;

   }

   if (NULL ==oractx->envhp)

   {

      LogMessage("oractx->envhp==NULL inora_execute().");

      delete pszGBKSQL;

      return -2;

   }

   retcode= OCIHandleAlloc( (dvoid *) oractx->envhp, (dvoid **) &stmthp,OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);

   ora_check_error(oractx->errhp,retcode,&errcode);

   if (0!=retcode || NULL==stmthp)

   {

      LogMessage("OCIHandleAlloc()failed in ora_execute().");

      delete pszGBKSQL;

      return -3;

   }

   retcode= OCIStmtPrepare(stmthp, oractx->errhp, (text *)pszGBKSQL,  (ub4) strlen(pszGBKSQL), (ub4)OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT);

   ora_check_error(oractx->errhp,retcode, &errcode);

   if(retcode!=OCI_SUCCESS&& retcode!=OCI_SUCCESS_WITH_INFO)

   {

      LogMessage("OCIStmtPrepare() failed %d,%d. reconnect ORACLE,sql=%s", retcode,errcode,pszGBKSQL);

      if(errcode != 1756)

      {

         OCIHandleFree(stmthp,OCI_HTYPE_STMT);

         ora_clean(oractx);

         delete pszGBKSQL;

         return -4;

      }

      LogMessage("Error 1756, minor error, ignore it.");

      OCIHandleFree(stmthp,OCI_HTYPE_STMT);

      delete pszGBKSQL;

      return 0;

   }

   //綁定3個輸入變量

 

   if ((retcode=OCIBindByPos(stmthp,  &bidhp[0],oractx->errhp,(ub4) 1, (dvoid *)userid,(sb4)(strlen(userid)+1),SQLT_STR,NULL, NULL, NULL, 0, NULL, (ub4)OCI_DEFAULT))!=OCI_SUCCESS)

   {

      ora_check_error(oractx->errhp,retcode, &errcode);

      LogMessage("ora_procedure_execute Error when OCIBindByPos userid\n");

      return -9;

   }

   if ((retcode=OCIBindByPos(stmthp,  &bidhp[1],oractx->errhp,(ub4) 2, (dvoid *)exptype,(sb4)(strlen(exptype)+1),SQLT_STR,NULL, NULL, NULL, 0, NULL, (ub4)OCI_DEFAULT))!=OCI_SUCCESS)

   {

      ora_check_error(oractx->errhp,retcode, &errcode);

      LogMessage("ora_procedure_execute Error when OCIBindByPos exptype\n");

      return -9;

   }

   if ((retcode=OCIBindByPos(stmthp,  &bidhp[2],oractx->errhp,(ub4) 3, (dvoid*)conditionexp,(sb4)(strlen(conditionexp)+1),SQLT_STR, NULL, NULL, NULL, 0,NULL, (ub4)OCI_DEFAULT))!=OCI_SUCCESS)

   {

      ora_check_error(oractx->errhp,retcode, &errcode);

      LogMessage("ora_procedure_execute Error when OCIBindByPos conditionexp\n");

      return -9;

   }

 

   //定義3個變量存儲輸出參數

   char szResult[4096];

   memset(szResult,0,sizeof(szResult));

   int nErrorcode = 0 ;

   char szErrorMsg[4096];

   memset(szErrorMsg,0,sizeof(szErrorMsg));

 

   if ((retcode= OCIBindByPos(stmthp, &bidhp[3], oractx->errhp,(ub4)4,(dvoid*)(szResult),(sword)4096, SQLT_STR, &sb2aInd[0], NULL, NULL, 0, NULL,  (ub4)OCI_DEFAULT))!=OCI_SUCCESS)

   {

      ora_check_error(oractx->errhp,retcode, &errcode);

      LogMessage("ora_procedure_execute Error when OCIBindByNamebusiness_date \n");

      return -9;

   }

   if ((retcode=OCIBindByPos(stmthp, &bidhp[4], oractx->errhp,(ub4)5,(&nErrorcode),(sizeof(int)),SQLT_INT,&sb2aInd[1], NULL, NULL, 0, NULL,(ub4)OCI_DEFAULT))!=OCI_SUCCESS)

   {

      ora_check_error(oractx->errhp,retcode, &errcode);

      LogMessage("ora_procedure_execute Error when OCIBindByNamebussiness_nodeid \n");

      return -9;

   }

   if ((retcode=OCIBindByPos(stmthp, &bidhp[5], oractx->errhp,(ub4)6, (dvoid*)(szErrorMsg), (sword)4096,SQLT_STR, &sb2aInd[2], NULL, NULL, 0, NULL,(ub4)OCI_DEFAULT))!=OCI_SUCCESS)

   {

      ora_check_error(oractx->errhp,retcode, &errcode);

      LogMessage("ora_procedure_execute Error when OCIBindByNamebusiness_date \n");

      return -9;

   }

  retcode= OCIStmtExecute(oractx->svchp, stmthp, oractx->errhp, (ub4) 1,(ub4)0,  (OCISnapshot *)NULL,(OCISnapshot*)NULL,(ub4)OCI_DEFAULT);

   ora_check_error(oractx->errhp, retcode, &errcode);

   if (0!=retcode)

   {

      LogMessage("OCIStmtExecute() failed. retcode=%d,errcode=%d,sql:%s", retcode, errcode, pszGBKSQL);

      if (OCI_ERROR==retcode&& errcode!=1756)

      {

         LogMessage("OCIStmtExecute() failed. error occured,disconnect");

         OCIHandleFree(stmthp,OCI_HTYPE_STMT);

         ora_clean(oractx);

         delete pszGBKSQL;

         return -5;

      }

   }

   *errorcode= nErrorcode;

   *errormsg= newchar[sizeof(szErrorMsg) + 1];

   memcpy(*errormsg,(char*)szErrorMsg,strlen(szErrorMsg)+ 1);

   *resultof= newchar[sizeof(szResult) + 1];

   memcpy(*resultof,(char*)szResult,strlen(szResult)+ 1);

   //commit

   if((retcode=OCITransCommit(oractx->svchp, oractx->errhp, (ub4) 0)) !=OCI_SUCCESS)

   {

      ora_check_error(oractx->errhp,retcode, &errcode);

      LogMessage("ora_dbbind_execute Error when OCIStmtCommit\n");

      return -6;

   }

   delete pszGBKSQL;

   OCIHandleFree(stmthp,OCI_HTYPE_STMT);

   return 0;

}

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章