以下に、入力 SQLDA 構造の使用方法を示すサンプル・プログラムを挙げます。クライアント・アプリケーションは、Presidents という名前の表を作成し、その表にデータをロードするストアード・プロシージャーを呼び出します。
このプログラムにより、Presidents という名前の表が SAMPLE データベース内に作成されます。次いで、表中に Washington、Jefferson、および Lincoln という値を挿入します。
ストアード・プロシージャーを使用しないと、このサンプル・プログラムは図 23 に示すように、各 SQL ステートメントを処理するために 4 つの別個の要求でネットワークを経由してデータを伝送するように設計されます。
図 23. ストアード・プロシージャーを使用しない場合の入力 SQLDA の例
![]() |
これとは異なり、サンプル・プログラムがストアード・プロシージャーの技法を活用して 1 つの要求ですべてのデータをネットワークを経由して伝送する場合には、サーバー・プロシージャーが SQL ステートメントをグループとして実行することが可能になります。この技法は図 24 に示されています。
図 24. ストアード・プロシージャーを使用する場合の入力 SQLDA の例
![]() |
入力 SQLDA クライアント・アプリケーション、および入力 SQLDA ストアード・プロシージャーの例を 入力 SQLDA クライアント・アプリケーション例の動作の仕組みに示します。
CHECKERR マクロ / 関数は、プログラム外部にあるエラー検査ユーティリティーです。エラー検査ユーティリティーの所在は、ご使用のプログラミング言語により異なります。
このエラー検査ユーティリティーのソース・コードについては、 プログラム例での GET ERROR MESSAGE の使用を参照してください。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sqlenv.h> #include <sqlca.h> #include <sqlda.h> #include <sqlutil.h> #include "util.h" #define CHECKERR(CE_STR) if (check_error (CE_STR, &sqlca) != 0) return 1; int main(int argc, char *argv[]) { EXEC SQL BEGIN DECLARE SECTION; char database[9]; char userid[9]; char passwd[19]; char procname[255] = "inpsrv"; char table_name[11] = "PRESIDENTS"; char data_item0[21] = "Washington"; char data_item1[21] = "Jefferson"; char data_item2[21] = "Lincoln"; short tableind, dataind0, dataind1, dataind2; EXEC SQL END DECLARE SECTION; /* Declare Variables for CALL USING */ struct sqlca sqlca; struct sqlda *inout_sqlda = NULL; char eBuffer[1024]; /* error message buffer */ if (argc != 4) { printf ("\nUSAGE: inpcli remote_database userid passwd\n\n"); return 1; } strcpy (database, argv[1]); strcpy (userid, argv[2]); strcpy (passwd, argv[3]); /* Connect to Remote Database */ printf("CONNECT TO Remote Database.\n"); EXEC SQL CONNECT TO :database USER :userid USING :passwd; CHECKERR ("CONNECT TO SAMPLE"); /********************************************************\ * Call the Remote Procedure via CALL with Host Variables * \********************************************************/ printf("Use CALL with Host Variable to invoke the Server Procedure" " named inpsrv.\n"); tableind = dataind0 = dataind1 = dataind2 = 0; EXEC SQL CALL :procname (:table_name:tableind, :data_item0:dataind0, :data_item1:dataind1, :data_item2:dataind2); (2a) /* COMMIT or ROLLBACK the transaction */ if (SQLCODE == 0) { EXEC SQL COMMIT; printf("Server Procedure Complete.\n\n"); } else { /* print the error message, roll back the transaction and return */ sqlaintp (eBuffer, 1024, 80, &sqlca); printf("\n%s\n", eBuffer); EXEC SQL ROLLBACK; printf("Server Procedure Transaction Rolled Back.\n\n"); return 1; } /* Allocate and Initialize Input SQLDA */ (1) inout_sqlda = (struct sqlda *)malloc( SQLDASIZE(4) ); inout_sqlda->sqln = 4; inout_sqlda->sqld = 4; inout_sqlda->sqlvar[0].sqltype = SQL_TYP_NCSTR; inout_sqlda->sqlvar[0].sqldata = table_name; inout_sqlda->sqlvar[0].sqllen = strlen( table_name ) + 1; inout_sqlda->sqlvar[0].sqlind = &tableind; inout_sqlda->sqlvar[1].sqltype = SQL_TYP_NCSTR; inout_sqlda->sqlvar[1].sqldata = data_item0; inout_sqlda->sqlvar[1].sqllen = strlen( data_item0 ) + 1; inout_sqlda->sqlvar[1].sqlind = &dataind0; inout_sqlda->sqlvar[2].sqltype = SQL_TYP_NCSTR; inout_sqlda->sqlvar[2].sqldata = data_item1; inout_sqlda->sqlvar[2].sqllen = strlen( data_item1 ) + 1; inout_sqlda->sqlvar[2].sqlind = &dataind1; inout_sqlda->sqlvar[3].sqltype = SQL_TYP_NCSTR; inout_sqlda->sqlvar[3].sqldata = data_item2; inout_sqlda->sqlvar[3].sqllen = strlen( data_item2 ) + 1; inout_sqlda->sqlvar[3].sqlind = &dataind2; /***********************************************\ * Call the Remote Procedure via CALL with SQLDA * \***********************************************/ printf("Use CALL with SQLDA to invoke the Server Procedure named " "inpsrv.\n"); tableind = dataind0 = dataind1 = dataind2 = 0; inout_sqlda->sqlvar[0].sqlind = &tableind; inout_sqlda->sqlvar[1].sqlind = &dataind0; inout_sqlda->sqlvar[2].sqlind = &dataind1; inout_sqlda->sqlvar[3].sqlind = &dataind2; EXEC SQL CALL :procname USING DESCRIPTOR :*inout_sqlda; (2b) /* COMMIT or ROLLBACK the transaction */ if (SQLCODE == 0) { EXEC SQL COMMIT; printf("Server Procedure Complete.\n\n"); } else { /* print the error message, roll back the transaction and return */ sqlaintp (eBuffer, 1024, 80, &sqlca); printf("\n%s\n", eBuffer); EXEC SQL ROLLBACK; printf("Server Procedure Transaction Rolled Back.\n\n"); return 1; } /* Free allocated memory */ free( inout_sqlda ); /* Drop the PRESIDENTS table created by the stored procedure */ EXEC SQL DROP TABLE PRESIDENTS; CHECKERR("DROP TABLE"); /* Disconnect from Remote Database */ EXEC SQL CONNECT RESET; CHECKERR ("CONNECT RESET"); return 0; } /* end of program : inpcli.sqc */
注: | サーバー・プロシージャーは、AIX システム上では REXX で作成することはできません。 |
#include <memory.h> #include <string.h> #include <sqlenv.h> #include <sqlutil.h> #ifdef __cplusplus extern "C" #endif SQL_API_RC SQL_API_FN inpsrv(void *reserved1, (1) void *reserved2, struct sqlda *inout_sqlda, struct sqlca *ca) { /* Declare a local SQLCA */ EXEC SQL INCLUDE SQLCA; /* Declare Host Variables */ EXEC SQL BEGIN DECLARE SECTION; char table_stmt[80] = "CREATE TABLE "; char insert_stmt[80] = "INSERT INTO "; char insert_data[21]; EXEC SQL END DECLARE SECTION; /* Declare Miscellanous Variables */ int cntr = 0; char *table_name; char *data_items[3]; short data_items_length[3]; int num_of_data = 0; /*-----------------------------------------------------------------*/ /* Assign the data from the SQLDA to local variables so that we */ /* don't have to refer to the SQLDA structure further. This will */ /* provide better portability to other platforms such as DB2 MVS */ /* where they receive the parameter list differently. */ /*-----------------------------------------------------------------*/ table_name = inout_sqlda->sqlvar[0].sqldata; num_of_data = inout_sqlda->sqld - 1; for (cntr = 0; cntr < num_of_data; cntr++) { data_items[cntr] = inout_sqlda->sqlvar[cntr+1].sqldata; data_items_length[cntr] = inout_sqlda->sqlvar[cntr+1].sqllen; } /*-----------------------------------------------------------------*/ /* Create President Table */ /* - For simplicity, we'll ignore any errors from the */ /* CREATE TABLE so that you can run this program even when the */ /* table already exists due to a previous run. */ /*-----------------------------------------------------------------*/ EXEC SQL WHENEVER SQLERROR CONTINUE; strcat(table_stmt, table_name); strcat(table_stmt, " (name CHAR(20))"); (2) EXEC SQL EXECUTE IMMEDIATE :table_stmt; EXEC SQL WHENEVER SQLERROR GOTO ext; /*-----------------------------------------------------------------*/ /* Generate and execute a PREPARE for an INSERT statement, and */ /* then insert the three presidents. */ /*-----------------------------------------------------------------*/ strcat(insert_stmt, table_name ); strcat(insert_stmt, " VALUES (?)"); (3) EXEC SQL PREPARE S1 FROM :insert_stmt; for (cntr = 0; cntr < num_of_data; cntr++) { strncpy(insert_data, data_items[cntr], data_items_length[cntr]); insert_data[data_items_length[cntr]] = '\0'; EXEC SQL EXECUTE S1 USING :insert_data; (4) } /*-----------------------------------------------------------------*/ /* Return to caller */ /* - Copy the SQLCA */ /* - Update the output SQLDA. Since there's no output to */ /* return, we are setting the indicator values to -128 to */ /* return only a null value. */ /*-----------------------------------------------------------------*/ ext: (5) memcpy(ca, &sqlca, sizeof(struct sqlca)); if (inout_sqlda != NULL) { for (cntr = 0; cntr < inout_sqlda->sqld; cntr++) { *(inout_sqlda->sqlvar[cntr].sqlind) = -128; } } return(SQLZ_DISCONNECT_PROC); }