Das folgende Beispiel erstellt eine gespeicherte Prozedur, eine Subskription für die gespeicherte Prozedur und eine DB2 Everyplace-Anwendung, die die gespeicherte Prozedur verwendet. Der Zweck der Beispielanwendung ist es, einem mobilen Benutzer die Überprüfung seines Kontostands und die Übertragung von Geld zwischen seinem Spar- und Girokonto zu ermöglichen, indem er den Aufruf einer fernen gespeicherten Prozedur in DB2 Everyplace verwendet. Informationen zum Erstellen von gespeicherten Prozeduren in DB2 Universal Database finden Sie im Handbuch DB2 Universal Database Application Development Guide.
Erstellen einer Datenquelle
Dieses Beispiel verwendet eine DB2-Datenbank mit dem Namen MYSAMPLE. Sie müssen die Datenbank MYSAMPLE manuell erstellen. Geben Sie die folgenden Anweisungen an der DB2-Eingabeaufforderung ein, um die Datenbank MYSAMPLE zu erstellen:
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)
Erstellen Sie eine gespeicherte Prozedur, um die Daten in der Datenbank zu verändern, nachdem Sie die Datenbank erstellt haben.
Erstellen einer gespeicherten Prozedur
Dieses Beispiel verwendet eine gespeicherte Prozedur mit dem Namen MYPROC(). Diese Prozedur verarbeitet fünf Parameter: Kontoname (szName), Option (nCmd), Übertragungssumme (nAmount), Kontostand Sparkonto (nSaving) und Kontostand Girokonto (nChecking). In der folgenden Liste ist der Zweck der Parameter angegeben:
Kontoname: Eingabeparameter zur Angabe des Kontos Option: Eingabeparameter zur Bestimmung der Aktion. Es gibt drei Optionen: 1: Kontostand überprüfen 2: Übertragung vom Sparkonto auf das Girokonto 3: Übertragung vom Girokonto auf das Sparkonto Übertragungssumme: Eingabeparameter für die Summe, die zwischen dem Girokonto und dem Sparkonto übertragen werden soll. Kontostand Sparkonto: Ausgabeparameter, der den Kontostand des Sparkontos zurückgibt Kontostand Girokonto: Ausgabeparameter, der den Kontostand des Girokontos zurückgibt
Der folgende Code erstellt die gespeicherte Prozedur:
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); }
Kopieren Sie auf einer Win32-Plattform die gespeicherte Prozedur nach dem Erstellen in einer Dynamic Link Library (mydll.dll) in das Verzeichnis \SQLLIB\function. Registrieren Sie danach die gespeicherte Prozedur.
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'@
Geben Sie den folgenden Befehl ein, um das Script auszuführen:
db2 -td@ -vf regscript.scr
Die gespeicherte Prozedur db2e.MYPROC ist jetzt konfiguriert. Erstellen Sie nun eine Subskription mit Mobile Devices Administration Center.
Erstellen der AgentAdapter-Subskription
dbname=mysample;procname=db2e.MYPROCmysample ist die Datenbank, die von der gespeicherten Prozedur verwendet wird. db2e.MYPROC ist der Name der gespeicherten Prozedur.
Erstellen Sie nach dem Erstellen einer AgentAdapter-Subskription einen Benutzer, eine Gruppe und eine Subskriptionsgruppe.
Erstellen einer DB2 Everyplace-Anwendung zur Verwendung des Adapters für ferne Abfragen und gespeicherte Prozeduren
Dieses Beispiel verwendet eine DB2 Everyplace-Win32-Konsolanwendung, um den Adapter für ferne Abfragen und gespeicherte Prozeduren zu testen. Die Beispielanwendung hat den Namen myclient.exe. Die Beispielanwendung verwendet die folgenden drei Parameter:
Kontoname: Gibt das Konto an, auf das zugegriffen werden soll. Option: Gibt die auszuführende Aktion an. Es gibt die folgenden Optionen: 1: Kontostand überprüfen 2: Übertragung vom Sparkonto auf das Girokonto 3: Übertragung vom Girokonto auf das Sparkonto Summe: Zwischen Giro- und Sparkonto zu übertragende Summe
Geben Sie z. B. folgenden Befehl ein, um für das Konto "Michael" 1000 DM vom Sparkonto auf das Girokonto zu übertragen:
myclient.exe Michael 2 1000
Die folgende Antwort wird zurückgegeben:
Saving = 4000 Checking = 6000
Beispielanwendungscode
Der folgende Abschnitt enthält den Code der Beispielanwendung. Der Code erfordert eine Verbindungszeichenfolge für die Funktion SQLConnect(), um eine Verbindung zu der fernen Datenquelle herzustellen. Die Verbindungszeichenfolge hat das folgende Format:
http://IPAddr:port/db2e/servlet/com.ibm.mobileservices.adapter.agent.AgentServlet?DB=mysample
Dabei ist IP-Addr:port die IP-Adresse und die Portnummer des Servers. Beispiel:
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; }
Testen Sie die Anwendung für den Adapter für ferne Abfragen und gespeicherte Prozeduren, nachdem Sie die Beispielanwendung kompiliert haben.