• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            山寨:不是最好的,是最適合我們的!歡迎體驗(yàn)山寨 中文版MSDN

            Blog @ Blog

            當(dāng)華美的葉片落盡,生命的脈絡(luò)才歷歷可見(jiàn)。 -- 聶魯達(dá)

            常用鏈接

            統(tǒng)計(jì)

            積分與排名

            BBS

            Blog

            Web

            最新評(píng)論

            VC中使用ADO調(diào)用存儲(chǔ)過(guò)程實(shí)現(xiàn)方法

            開(kāi)發(fā)環(huán)境是VS2005  ,數(shù)據(jù)庫(kù)是SQL Sever 2000

            1. 在進(jìn)入正題之前,先講點(diǎn)別的,如何在VC中連接Sybase數(shù)據(jù)庫(kù),

               連接字符竄為,

              _bstr_t strCnn(\"Driver={Sybase System 11};Srvr=RRRRR;Uid=RRR_Mao_bb1;Pwd=user2\");

            這里,RRRRR是數(shù)據(jù)庫(kù)的名稱,已經(jīng)在Sybase->sdedit中設(shè)定好了

             RRR_Mao_bb1 和 user2分別是用戶名和密碼

             不過(guò)使用這種基于ODBC的連接使用一段時(shí)間以后,就出現(xiàn)問(wèn)題了,出現(xiàn)了“Catastrophic failure”的錯(cuò)誤,微軟的解釋是  http://support.microsoft.com/kb/243349/en-us

             

            2. 為了使我們的調(diào)用存儲(chǔ)過(guò)程的例子有更多的通用性,我建了有輸入?yún)?shù),有輸出參數(shù),有一個(gè)返回記錄集,有一個(gè)返回值的存儲(chǔ)過(guò)程,如下

              
            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

            對(duì)于這個(gè)SP來(lái)說(shuō),他這些個(gè)參數(shù)是

            @RETURN_VALUE(int ,返回值)  

            @pin1 ( int  ,輸入 )  

            @pin2 ( char(10)  ,輸入 ) 

            @pout1 (int ,輸入/輸出) 

            @pout1 ( char(10)  , 輸入/輸出)  

            @RETURN_VALUE是第0個(gè)參數(shù),@pin1是第1個(gè),依此類推

            以上信息可以在SQL 的查詢分析器中看到,注意,這些參數(shù)的順序很重要

             

            3.調(diào)用的前期準(zhǔn)備

              這就不多說(shuō)了,什么import 庫(kù)阿,建立連接阿,什么的,不多說(shuō)了,

             這些在 VC中使用ADO進(jìn)行數(shù)據(jù)庫(kù)開(kāi)發(fā)的一些資料的整理 中有了闡述

            假定連接是pConn

            注意,這里要把pConn設(shè)定成adUseClient型[Page]

            pConn->CursorLocation =adUseClient;

            下面我要貼具體的代碼了,為了精簡(jiǎn)所貼的代碼,我把所有的捕獲異常都沒(méi)貼出來(lái)(try catch)

             

            4.使用Refresh的方法來(lái)調(diào)用

            先定義一些變量

             _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參數(shù)賦值

             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\");  

            這個(gè)refresh一定要有,

            調(diào)SP

            pRecordset =  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);

             //取記錄集里面的內(nèi)容


              if (pRecordset->adoBOF && pRecordset->adoEOF)
              {
               MessageBox(\"沒(méi)有符合條件的記錄存在!\",\"提示\");

               if(pRecordset != NULL && pRecordset->State)
               {
                pRecordset->Close();
                pRecordset = NULL; 

            }

             

               pCmd.Detach();
               return;
              }
             
              pRecordset->MoveFirst();
             
              for(;!pRecordset->adoEOF;pRecordset->MoveNext())
              {
               VRectVal = pRecordset->GetCollect(_T(\"Name\"));
               StrVal = (LPCTSTR)_bstr_t(VRectVal);
               m_list.AddString(StrVal);
              }
             

              if(pRecordset != NULL && pRecordset->State)
              {
               pRecordset->Close();
               pRecordset = NULL;  [Page]
              }

            最后pCmd.Detach();

             在這里,有一點(diǎn)要注意的是

            VretVal = pCmd->Parameters->GetItem(short(4))->Value;
            這里的4,就是哪個(gè)output參數(shù)的index,就是我在2中說(shuō)的參數(shù)的順序

            這里使用了Refresh,這是一個(gè)很重要的函數(shù),我將在下面介紹一下它,我要先貼出另一種,不使用Refresh的辦法,

            5 .使用非Refresh的方法來(lái)調(diào)用

            先定義變量

            _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

             retParam = pCmd ->CreateParameter(_bstr_t(\"Return\"),
                                             adInteger,
                        adParamReturnValue,
                        sizeof(int));
              pCmd->Parameters->Append(retParam);

             
             
                    inParam1  = pCmd ->CreateParameter(_bstr_t(\"InParam1\"),
                                             adInteger,
                        adParamInput,
                        sizeof(int));

              inParam1->Value = _variant_t(3);

              pCmd->Parameters->Append(inParam1);


              inParam2  = pCmd ->CreateParameter(_bstr_t(\"InParam2\"),
                                             adChar,
                        adParamInput,[Page]
                        10);
             
              inParam2->Value = _variant_t(_T(\"DD1\"));

              pCmd->Parameters->Append(inParam2);


              outParam1 = pCmd ->CreateParameter(_bstr_t(\"OutParam1\"),
                                             adInteger,
                        adParamOutput,
                        sizeof(int));
              pCmd->Parameters->Append(outParam1);


              outParam2 = pCmd ->CreateParameter(_bstr_t(\"OutParam2\"),
                                             adChar,
                        adParamOutput,
                        10);
              pCmd->Parameters->Append(outParam2);

             

            這里不用refresh的辦法,是用Parameter來(lái),這里要注意的是,這個(gè)add的順序要和參數(shù)的index順序要一致

            下面就是調(diào)用了

            pRecordset =  pCmd->Execute(NULL,NULL,adCmdStoredProc);

            然后取那些return值阿,output值阿什么的

            這里有一個(gè)區(qū)別,就是用這種辦法

            可以有三種辦法來(lái)取這些返回值和output參數(shù)

            VretVal = pCmd->Parameters->GetItem(_bstr_t(\"Return\"))->Value;
            VretVal = pCmd->Parameters->GetItem(short(0))->Value;
             VretVal = retParam->Value;

            都是一樣的

            6. 關(guān)于Refresh

            關(guān)于這個(gè)函數(shù),作用是

            Command   對(duì)象去重新索取要操作的存儲(chǔ)過(guò)程所有有關(guān)參數(shù)的信息,并且清空在refresh之前獲取的參數(shù)信息。  

            所以一但調(diào)用它以后,就可以獲取SP的那些信息,那些參數(shù)的信息,可以通過(guò)pCmd->Parameters->Item[_variant_t(_bstr_t(\"@pin1\") )]->Value=_variant_t(3);   這樣的方式來(lái)設(shè)置參數(shù)

            如果要使用Parameter的辦法的話,就不要用refresh了,事實(shí)上,如果先把這些參數(shù)的值設(shè)置好了,如  inParam2->Value = _variant_t(_T(\"DD1\"));,一旦refresh后,這些參數(shù)就沒(méi)有意義了。

            7.關(guān)于pConn->CursorLocation =adUseClient;

             設(shè)置這個(gè)東西,如果不設(shè)置游標(biāo)為adUseClient,那么我在取return和output參數(shù)的時(shí)候,必須在我把記錄集關(guān)閉以后才能取,就是說(shuō),必須先取記錄集,然后關(guān)閉它,最后再取return和output參數(shù),如果我在關(guān)閉記錄集之前就取return和output的值,那么就不能取到正確的值,設(shè)成adUseClient就ok了,

            另外有一點(diǎn)就是,Execute 方法返回的游標(biāo)繼承該設(shè)置。Recordset 將自動(dòng)從與之關(guān)聯(lián)的連接中繼承該設(shè)置。我把pConn設(shè)成adUseClient,那么最后,我的記錄集也是adUseClient的了[Page]

            posted on 2008-06-17 23:39 isabc 閱讀(4273) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 數(shù)據(jù)庫(kù)

            廣告信息(免費(fèi)廣告聯(lián)系)

            中文版MSDN:
            歡迎體驗(yàn)

            久久久久久久综合综合狠狠| 国产巨作麻豆欧美亚洲综合久久 | 久久99热精品| 久久精品人人做人人爽电影蜜月| 亚洲va久久久噜噜噜久久天堂 | 7777精品伊人久久久大香线蕉| 久久影院午夜理论片无码| 欧美性猛交xxxx免费看久久久| 亚洲国产成人久久笫一页| 久久AV无码精品人妻糸列| 久久久久亚洲AV片无码下载蜜桃| 99久久久国产精品免费无卡顿| 国产成人精品久久一区二区三区| 久久国产精品99久久久久久老狼| 一本久久a久久精品综合夜夜| 国产精品嫩草影院久久| 久久久免费观成人影院 | 97久久精品无码一区二区| 麻豆精品久久久一区二区| 久久久久久久久久免免费精品| 久久无码专区国产精品发布| 久久久久久亚洲精品成人| 欧美亚洲国产精品久久蜜芽| 欧洲性大片xxxxx久久久| 97久久婷婷五月综合色d啪蜜芽| 99久久久精品免费观看国产| 久久国产美女免费观看精品| 久久丫忘忧草产品| 狠狠人妻久久久久久综合| 久久人人爽人人爽人人av东京热| 7777久久亚洲中文字幕| 亚洲精品97久久中文字幕无码| 国产∨亚洲V天堂无码久久久| 久久久精品波多野结衣| 久久久精品国产sm调教网站| 久久综合久久性久99毛片| 精品无码久久久久久午夜| 久久人人爽人人爽人人片AV麻豆| 国内精品久久久人妻中文字幕| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 久久精品国产亚洲Aⅴ香蕉|