Sync Server 管理指南


使用远程查询和存储过程适配器的样本应用程序

以下示例将创建存储过程、存储过程的预订和 DB2 Everyplace 应用程序来使用存储过程。示例应用程序的目的是让移动用户能够通过使用 DB2 Everyplace 远程存储过程调用来检查帐户余额, 并在储蓄帐户和支票帐户间转钱。有关如何在“DB2 通用数据库”中创建存储过程的信息,请查看《DB2 通用数据库应用程序开发指南》。

创建数据源

本示例使用名为 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 目录。然后,注册存储过程。

  1. 打开 DB2 命令窗口。
  2. 使用以下命令连接至 MYSAMPLE 数据库:
    DB2 CONNECT TO MYSAMPLE
    
  3. 使用名为 regscript.scr 的脚本注册存储过程以配置选项。下列代码用于此脚本:
    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'@
    

    要运行脚本,输入下列命令:

    db2 -td@ -vf regscript.scr
    

现在配置存储过程 db2e.MYPROC。然后,使用“移动设备管理中心”创建预订。

创建 AgentAdapter 预订

  1. 从开始菜单打开“移动设备管理中心”。
  2. 选择“移动设备管理中心”的预订文件夹。
  3. 右键单击“移动设备管理中心”的预订文件夹并选择创建定制预订
  4. 名称字段中输入 subex
  5. 适配器字段中选择 AgentAdapter。
  6. 加密字段中选择“无”。AgentAdapter 不支持加密。
  7. 单击启动定制器按钮。“源数据库”窗口打开。
  8. 用户标识字段中输入对数据库具有访问特权的 DB2 用户标识
  9. 密码验证密码字段中输入用户标识的密码。
  10. 其他字段中,输入下面这一行:
    dbname=mysample;procname=db2e.MYPROC
    
    dbname 是存储过程使用的数据库。procname 是存储过程的名称。
  11. 单击确定来关闭“源数据库”窗口。单击确定来关闭 “创建定制预订”笔记本。

创建 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;
}
 

编译完样本应用程序后,测试远程查询和存储过程适配器应用程序。


[ 页的顶部 | 上一页 | 下一页 | 目录 | 索引 ]