• <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>

            Prayer

            在一般中尋求卓越
            posts - 1256, comments - 190, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            用CLI開發(fā)DB2存儲過程

            Posted on 2009-03-30 16:16 Prayer 閱讀(739) 評論(0)  編輯 收藏 引用 所屬分類: DB2
            王隆彥


              前 言


              在用大型關系型數據庫DB2進行具體開發(fā)時,存儲過程的編寫是經常要考慮的問題之一。本文將結合實例,對使用CLI來開發(fā)DB2存儲過程進行詳細闡述。


              ■DB2存儲過程


              存儲過程(Store Procedure)是Client/Server應用中的一種編程方式,主要是為了解決客戶端應用訪問數據庫時可能出現(xiàn)的網絡負擔過重的問題。

              一般意義上,DB2為存儲過程的編寫提供了三種方式(不包括直接使用DB2的Store Procedure Builder生成的方式):第一種是嵌入式SQL編程;第二種是CLI編程;第三種是純SQL編程。本文將重點介紹CLI編程。


              ■CLI編程


              CLI(Call Level Interface)編程是DB2提供的一種編寫動態(tài)數據庫讀寫程序的方式。在CLI編程中,所有SQL語句都通過DB2提供的一組C語言函數來執(zhí)行,因此可以在Visual Studio中直接開發(fā)。下面,我們首先要簡單介紹一下CLI的工作過程和方式。

              CLI程序主要由三個部分組成:首先是環(huán)境變量初始化過程,其次是語句的執(zhí)行,最后是環(huán)境變量的釋放。我們將通過一個具體的例子來討論這三個過程。


              ■開發(fā)實例


              該例子的數據庫是DB2可以自動生成的Sample庫,例子所完成的操作是從數據庫中獲取ID等于輸入參數值的員工姓名,例子的整個過程雖然非常簡單,但已經包含了CLI編程的基本思路和步驟。

              1. 初始化環(huán)境變量

              在CLI中有三個句柄,分別是環(huán)境句柄、連接句柄、語句句柄。在初始化過程中首先要對前兩個句柄逐一進行獲取,獲取成功后可連接數據庫并獲取第三個句柄。

              SQLRETURN ret;

              SQLHENV henv; // 環(huán)境句柄

              SQLHDBC hdbc; // 連接句柄

              SQLHSTMT hstmt; // 語句句柄

              SQLCHAR DBNAME[]="SAMPLE"; //數據庫名

              SQLCHAR USERNAME[]="db2admin"; // 用戶名

              SQLCHAR PSW[]="ibmdb2"; // 口令

              ret=SQLAllocEnv(&&henv) //分配環(huán)境句柄

              ret=SQLAllocConnect(henv,&&hdbc)

              //分配連接句柄

              ret=SQLSetConnectOption(hdbc,SQL_AUTOCOMMIT,SQL_AUTOCOMMIT_OFF)

              //設置連接屬性

              ret=SQLConnect(hdbc,DBNAME,SQL_NTS,USERNAME,SQL_NTS,PSW,SQL_NTS) //連接數據庫

              ret=SQLAllocStmt(hdbc,&&hstmt)

              //分配語句句柄

              上面的每個函數都有返回值,如果函數成功,ret值為SQL_SUCCESS,否則將返回錯誤代碼。

              2. 語句的執(zhí)行

              語句的執(zhí)行分四個階段:首先準備數據接收的緩沖區(qū),然后執(zhí)行準備好的SQL語句,第三步是將語句句柄和數據緩沖區(qū)進行綁定,最后獲取數據。程序如下:

              char RowBuffer[100][200];

              //數據緩沖區(qū),其大小可自定義

              typedef struct sqldat

              { SQLCHAR ColumnName[50];

               SQLSMALLINT BufferLength;

               SQLSMALLINT NameLength;

               SQLSMALLINT DataType;

               SQLUINTEGER ColumnSize;

               SQLSMALLINT FAR DecimalDigitsPtr;

               SQLSMALLINT FAR NullablePtr;

              } sqldata;

              // 為第三步的綁定準備一個數據結構

              sqldata RowDesc[100];

              //用于綁定的變量,維數與緩沖區(qū)對應

              memset(RowBuffer,64,100200);

              //給緩沖區(qū)賦初始值,可以用于最后判斷是否真正從數據庫中獲取了數據,這一步也可以省略

              char tempsql[100];

              sprintf(tempsql,"select NAME from db2admin.STAFF where ID= %s ",Condition);

              // Condition為變量值,可由用戶輸入

              sql=(SQLCHAR ) tempsql;

              ret=SQLPrepare(hstmt,sql,SQL_NTS)

              // 執(zhí)行準備

              ret=SQLExecute(hstmt) // 執(zhí)行

              執(zhí)行成功后可進行綁定過程

              SQLINTEGER nullindicator;

              SQLINTEGER displaysize[MAX_COLUMN];

              SQLSMALLINT i;

              SQLSMALLINT num_columns;

              SQLNumResultCols(hstmt,&&num_columns);

              //準備綁定用的相關變量

              for(i=1;i< =num_columns;i++)

               {

              RowDesc[i-1].BufferLength=200;

              SQLDescribeCol(hstmt,i, RowDesc[i-1].ColumnName,RowDesc[i-1].BufferLength,&&(RowDesc[i-1].NameLength),&&(RowDesc[i-1].DataType),&&(RowDesc[i-1].ColumnSize),RowDesc[i-1].DecimalDigitsPtr,RowDesc[i-1].NullablePtr);

              SQLColAttribute(hstmt,(SQLSMALLINT)(i),SQL_DESC_DISPLAY_SIZE,NULL,0,NULL,&&displaysize[i-1]);

              RowDesc[i-1].ColumnSize=max(displaysize[i-1],strlen((char)RowDesc[i-1].ColumnName))+1;

              SQLBindCol( hstmt, (SQLSMALLINT)i,

              SQL_C_CHAR,(SQLPOINTER)(RowBuffer[i-1]),RowDesc[i-1].ColumnSize,

              &&nullindicator);

              }//循環(huán)綁定

              //綁定完成后,可以將數據讀至緩沖區(qū)

              while(SQLFetch(hstmt)!=SQL_NO_DATA)

              {

              // SQLFetch函數將已經獲取的數據存入緩沖區(qū)

              //此處的操作方式與ESQL中的游標類似,支持對結果集的操作

              //每執(zhí)行一次SQLFetch函數會把當前獲取的一行數據讀到緩沖區(qū)中

              //RowBuffer[i]中將存放該行的第i 列數據值

              //本例中只有一行數據

              }

              char m_name[10];

              memcpy(m_name,RowBuffer[0],10);

              //從緩沖區(qū)中將結果讀到用戶變量中

              3. 釋放環(huán)境變量

              在數據獲取完成后,可以將環(huán)境變量釋放掉,但要注意釋放的先后順序。

              SQLFreeStmt(hstmt,SQL_DROP);

              // 釋放語句句柄

              SQLDisconnect(hdbc);//與數據庫斷開

              SQLFreeConnect(hdbc);//釋放連接句柄

              SQLFreeEnv(henv);//釋放環(huán)境句柄

              經過上面的步驟,就完成了對數據庫的讀取過程。

              4. 生成目標存儲過程

              從上面的過程看,CLI編程無疑是非常復雜的,但如果我們使用一些輔助手段來組織整個過程,其編程過程和調試步驟將會大大簡化。本文的例子使用了微軟的Visual Studio 6.0來幫助組織。在Visual C++中用Wizard生成一個DLL工程,然后將數據庫的初始化、綁定、釋放三個過程函數化,并在相應的地方調用函數。在調試時只需針對語句的執(zhí)行部分,合適的調試方式是不直接生成DLL,而先生成一個普通的EXE工程來完成所需的工作,待調試成功后將相關代碼移到DLL工程中。過程函數化的另一個好處是在編寫多個存儲過程時代碼重用率高,對于剛才提到的這種調試方式也很有利。使用Visual C++的優(yōu)點還有編譯和鏈接過程簡單,不用在命令行的方式下操作,也不需要去記憶許多復雜的參數。不過要記住將db2cli.lib包含進工程中,否則在鏈結過程中會有錯誤,還要做的一件事是按DLL工程中的要求編輯工程中的def文件以提供函數的可調用出口。

              在DLL生成并調試通過后,剩下的工作與ESQL編程方式中的相應階段類似,要手工編輯一個DB2文件并執(zhí)行它,這里就不再復述了。

            精品视频久久久久| 一本久久精品一区二区| 中文成人久久久久影院免费观看| 国产精品美女久久久久AV福利| 精品欧美一区二区三区久久久| 97久久精品人人做人人爽| 久久精品国产福利国产琪琪| 中文字幕精品久久久久人妻| 亚洲综合伊人久久综合| 精品久久久无码人妻中文字幕豆芽| 久久99精品久久久久久动态图| 99久久精品费精品国产一区二区| 久久中文娱乐网| 欧美亚洲国产精品久久久久| 久久av无码专区亚洲av桃花岛| 91久久精品国产成人久久| 伊人久久国产免费观看视频| 久久久久亚洲精品无码蜜桃| 九九久久精品无码专区| 久久夜色精品国产亚洲| 国产AV影片久久久久久| 亚洲国产精品无码久久一区二区| 99精品国产在热久久| 久久青青草视频| 久久99精品免费一区二区| 久久99精品国产麻豆| 国内精品伊人久久久影院| 久久综合综合久久狠狠狠97色88| 狠狠综合久久综合88亚洲| 国产亚洲美女精品久久久| 国产91色综合久久免费| 97久久国产露脸精品国产| 亚洲精品WWW久久久久久| 精品久久人人妻人人做精品| 精品国产乱码久久久久久郑州公司 | 国产V亚洲V天堂无码久久久| 亚洲精品国精品久久99热| 久久99精品久久久久久齐齐 | 色综合久久综合网观看| 大香伊人久久精品一区二区| 久久高清一级毛片|