下列範例將建立儲存程序、儲存程序的定期抄寫,以及使用儲存程序的 DB2 Everyplace 應用程式。 此範例應用程式的目的是容許行動使用者檢查帳戶餘額,以及在存款與支票帳戶之間使用 DB2 Everyplace 遠端儲存程序呼叫進行轉帳。如需如何在 DB2 Universal Database 中建立儲存程序的相關資訊,請參閱 DB2 Universal Database Application Development Guide。
建立資料來源
此範例使用名為 MYSAMPLE 的 DB2 資料庫。您需手動建立 MYSAMPLE 資料庫。若要建立 MYSAMPLE 資料庫,請於 DB2 指令提示中鍵入下列陳述式:
CREATE table db2e.MYACCOUNT ( Name char(16), Saving int, Checking int) INSERT into db2e.MYACCOUNT values('Michael', 5000, 5000) INSERT into db2e.MYACCOUNT values('Frank', 5000, 5000)
建好資料庫後,請建立一個儲存程序以修改資料庫中的資料。
建立儲存程序
此範例使用名為 MYPROC() 的儲存程序。此程序使用了 5 個參數: 帳戶名稱、選項、轉帳金額、儲蓄餘額、查詢餘額。 下列清單定義了每一個參數的用途:
帳戶名稱:識別帳戶的輸入參數。 選項:判定該進行什麼作業的輸入參數。有三個選項: 1: 查詢餘額。 2: 從儲蓄帳戶向支票帳戶轉帳。 3: 從支票帳戶向儲蓄帳戶轉帳。 轉帳金額:要在支票和儲蓄帳戶之間轉帳的金額輸入參數。 儲蓄余額:傳回儲蓄帳戶餘額資訊的輸出參數 查詢余額:傳回支票帳戶餘額資訊的輸出參數
下面是用來建置儲存程序的程式碼:
SQL_API_RC SQL_API_FN myProc(char * szName, int * nCmd, int * nAmount, int * nSaving, int * nChecking) { SQLHENV henv; SQLHDBC hdbc; SQLHSTMT hstmt; SQLRETURN rc; int nRetSize; SQLCHAR str1[]="select saving, checking from db2e.myaccount where name = ?"; SQLCHAR str2[]="update db2e.myaccount set saving=saving - ?, checking=checking + ? where name=?"; SQLCHAR str3[]="update db2e.myaccount set saving=saving + ?, checking=checking - ? where name=?"; //**************************************************************** //* Prepare connection and statement //**************************************************************** rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); //checkerror rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc); //checkerror rc = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, SQL_NTS); //checkerror rc = SQLConnect(hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS); //checkerror rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt); //checkerror //**************************************************************** //* Update account //**************************************************************** if ( *nCmd == 2 || *nCmd == 3 ){ if ( *nCmd == 2 ){ //Transfer from saving to checking rc = SQLPrepare(hstmt, str2, SQL_NTS); //checkerror } if ( *nCmd == 3 ){ //Transfer from checking to saving rc = SQLPrepare(hstmt, str3, SQL_NTS); //checkerror } rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, (SQLPOINTER)nAmount, 0, NULL ); //checkerror rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, (SQLPOINTER)nAmount, 0, NULL ); //checkerror rc = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 0, 0, (SQLPOINTER)szName, 0, NULL ); //checkerror rc = SQLExecute(hstmt); //checkerror } //**************************************************************** //* Retrieve account balance //**************************************************************** rc = SQLPrepare(hstmt, str1, SQL_NTS); //checkerror rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 0, 0, (SQLPOINTER)szName, 0, NULL );//checkerror rc = SQLExecute(hstmt);//checkerror if ( rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO ) { while ( (rc = SQLFetch(hstmt) ) == SQL_SUCCESS ){ rc = SQLGetData( hstmt, (SQLSMALLINT)1, SQL_C_LONG, nSaving, sizeof(int) , &nRetSize ) ; //checkerror rc = SQLGetData( hstmt, (SQLSMALLINT)2, SQL_C_LONG, nChecking, sizeof(int) , &nRetSize ) ; //checkerror } } //**************************************************************** //* Clean up //**************************************************************** rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ); SQLFreeHandle(SQL_HANDLE_STMT, hstmt); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return (0); }
在 Win32 平台中,在動態鏈結程式庫 (mydll.dll) 中建置了儲存程序之後,請將它複製至 \SQLLIB\function 目錄中。 下一步便是,註冊該儲存程序。
DB2 CONNECT TO MYSAMPLE
CREATE PROCEDURE db2e.MYPROC (IN szName CHAR(16), IN nCmd INTEGER, IN nAmount INTEGER, OUT nSaving INTEGER, OUT nChecking INTEGER ) DYNAMIC RESULT SETS 1 LANGUAGE C PARAMETER STYLE GENERAL NO DBINFO FENCED MODIFIES SQL DATA PROGRAM TYPE SUB EXTERNAL NAME 'mydll!myProc'@
若要執行該 Script,請輸入下列指令:
db2 -td@ -vf regscript.scr
儲存程序 db2e.MYPROC 現已配置好。接下來,請使用行動裝置管理中心建立定期抄寫。
建立代理程式配接卡定期抄寫
dbname=mysample;procname=db2e.MYPROC
dbname 是儲存程序使用的資料庫。procname 是儲存程序的名稱。
建好 AgentAdapter 定期抄寫設定之後,請新建一個使用者、群組及定期抄寫設定。
建立 DB2 Everyplace 應用程式以使用遠端查詢及儲存程序配接卡
此範例使用 DB2 Everyplace Win32 主控台應用程式對遠端查詢與儲存程序配接卡進行測試。 範例應用程式稱為 myclient.exe。該範例應用程式將使用到下列三個參數:
帳戶名稱:識別存取之帳戶。 選項:識別要執行的動作。這些選項有: 1: 查詢餘額。 2: 從儲蓄帳戶向支票帳戶的轉帳。 3: 從支票帳戶向儲蓄帳戶的轉帳。 金額:在支票帳戶與儲蓄帳戶之間轉帳的金額。
例如,若要從 Michael 的儲蓄帳戶向他的支票帳戶轉送 $1000 ,請輸入下列指令:
myclient.exe Michael 2 1000
就會傳回下列回應:
Saving = 4000 Checking = 6000
範例應用程式碼
下節包含範例應用程式的程式碼。 此程式碼需要 SQLConnect() 函數的連接字串,以便將其連接至遠端資料來源檔。 連接字串的格式為:
http://IPAddr:port/db2e/servlet/com.ibm.mobileservices.adapter.agent.AgentServlet?DB=mysample
其中 IPAddr:port 是伺服器的 IP 位址和埠號。 例如:
http://192.168.0.11:8080/db2e/servlet/ com.ibm.mobileservices.adapter.agent.AgentServlet?DB=mysample
int main(int argc, char * argv[]) { SQLHENV henv; SQLHDBC hdbc; SQLHSTMT hstmt; SQLRETURN rc; SQLCHAR strSQL[] = "CALL db2e.MYPROC(?,?,?,?,?)"; int nInd4, nInd5; int nSaving = 0, nChecking =0 ; int nCmd =0, nAmount=0; SQLCHAR strConnect[254]; //**************************************************************** //* Check input parameters //**************************************************************** if ( argc < 4 ){ printf("\nUsage : myClient AccountName Cmd Amount"); printf("\n cmd 1 : query balance"); printf("\n cmd 2 : Transfer from Saving to Checking"); printf("\n cmd 3 : Trnasfer from Checking to Saving"); return (99); } nCmd = atoi(argv[2]); nAmount = atoi(argv[3]); //**************************************************************** //* Allocate handles //**************************************************************** rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); //checkerror rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc); //checkerror if (argc == 5){ strcpy(strConnect,"http://"); strcat(strConnect,argv[4]); strcat(strConnect,"/db2e/servlet/com.ibm.mobileservices.adapter.agent.AgentServlet?DB=mysample"); }else{ strcpy(strConnect,"http://127.0.0.1:8080/db2e/servlet/com.ibm.mobileservices .adapter.agent.AgentServlet?DB=mysample"); } //**************************************************************** //* Connect to remote database //**************************************************************** rc = SQLConnect(hdbc, strConnect, SQL_NTS, "userex", SQL_NTS, "userex", SQL_NTS ); //checkerror rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt); //checkerror //**************************************************************** //* Prepare, Bind , and Execute the statement //**************************************************************** rc = SQLPrepare(hstmt,strSQL, SQL_NTS); //checkerror rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 0, 0, (SQLPOINTER)argv[1], 0, NULL ); //checkerror rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, (SQLPOINTER)&nCmd, sizeof(int), NULL); //checkerror rc = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, (SQLPOINTER)&nAmount, sizeof(int), NULL ); //checkerror rc = SQLBindParameter(hstmt, 4, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, (SQLPOINTER)&nSaving, sizeof(int), &nInd4); //checkerror rc = SQLBindParameter(hstmt, 5, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, (SQLPOINTER)&nChecking, sizeof(int), &nInd5 ); //checkerror rc = SQLExecute(hstmt); //checkerror //**************************************************************** //* Print the balance //**************************************************************** printf("\nSaving = %d",nSaving); printf("\nChecking = %d",nChecking); SQLFreeHandle(SQL_HANDLE_STMT, hstmt); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 0; }
在編譯了範例應用程式之後,請測試遠端查詢以及儲存程序配接卡應用程式。