sql_register_error_handler (user-error-routine, user-data)
戻り値はありません。
user-error-routine
アプリケーションのエラー処理ルーチンのアドレスです。
値: アプリケーションのエラー処理ルーチンのアドレス データ型: アドレス 受渡しメカニズム: 値
user-data
ユーザー指定のデータのアドレスです。
値: ユーザー指定のデータのアドレス データ型: アドレス 受渡しメカニズム: 値
sql_register_error_handlerルーチンにより、アプリケーションのエラー処理ルーチンがSQLに登録されます。SQLでは、SQLCODEに対して負の値を返すことが決定されると、現在登録されているエラー処理ルーチンがコールされます。特別なエラー処理ルーチンが登録されているかどうかとは関係なく、標準のエラー処理ルーチンは常に有効です。エラー処理ルーチンが実行された後、制御はSQLに返されます。アプリケーションでは、複数のエラー処理ルーチンを含めることもコールすることもできます。ただし、一度にアクティブとなるのは1つのルーチンのみです。
アプリケーションでは、sql_get_error_handlerルーチンを使用して、登録されているルーチンのアドレスを格納して後でプログラムで使用できます。
ルーチンの登録を解除するには、sql_deregister_error_handlerルーチンを使用します。
サポートされているプログラミング言語でエラー処理ルーチンを宣言する方法の詳細は、『Oracle Rdb7 Guide to SQL Programming』を参照してください。
- アプリケーションのエラー処理ルーチンでは、4つのパラメータを受け入れる必要があります。RDB$MESSAGE_VECTOR、SQLCODE、SQLSTATEの3つのパラメータは、参照によって渡されます。4番目のパラメータは、ユーザー指定のデータのアドレスであり、参照によって渡されます。
- 複数のエラー処理ルーチンをコールすると、最新の登録ルーチンが使用されます。
例5-1は、プリコンパイルされたCプログラムでSQLエラー処理ルーチンを使用する方法を示しています。
例5-1 SQLエラー処理ルーチンの使用
/* This program demonstrates the use of the SQL error handling routines, * sql_register_error_handler, sql_deregister_error_handler, and * sql_get_error_handler. Although the use of the sql_get_error_handler * routine is not necessary in this simple program, it is included here * to demonstrate how to use the routine to store the address of the * currently registered routine and the address of user data in variables. */ #include <sql_literals.h> /* Definition of rdb$message_vector. */ typedef struct { long RDB$LU_NUM_ARGUMENTS; long RDB$LU_STATUS; long RDB$LU_ARGUMENTS[18]; } RDB$MESSAGE_VECTOR; /* Definition of structure to hold user data. */ typedef struct { char sql_proc_name[31]; char sql_col_value[31]; } err_struct; /* Error handling routine for constraint violations. This routine traps * constraint violations and prints out an error message. */ static void dupl_error_handler( RDB$MESSAGE_VECTOR *msgvec, int *sqlcode, char *sqlstate, void *user_info) /* The preceding declaration for sqlcode refers to the internal sqlcode value, * a 32-bit quantity. */ { err_struct *my_info; my_info = (err_struct *)user_info; if ((*sqlcode == SQLCODE_INTEG_FAIL) && ((strcmp(my_info->sql_proc_name, "INSERT_JOBS")) == 0)) { printf(" The Job Code %s is already in use.\n", my_info->sql_col_value); } /* You can add more conditional statements to this error procedure to handle * errors from several SQL statements. */ } /* Error handling routine for errors that occur when you start a transaction. * This routine prints out an error message. */ static void txn_error_handler( RDB$MESSAGE_VECTOR *msgvec, int *sqlcode, char *sqlstate, void *user_info1) { if ((*sqlcode == SQLCODE_DEADLOCK) || (*sqlcode == SQLCODE_BAD_TXN_STATE) || (*sqlcode == SQLCODE_LOCK_CONFLICT)) printf("Unable to start a transaction. \n"); } main( ) { /* Variables used by the main program. */ void (*rtn_ptr)(); err_struct *err_struct_ptr = NULL; char j_code[5]; char w_class[2]; char j_title[21]; char release_screen; /* Define the SQLCA. */ EXEC SQL INCLUDE SQLCA; /* Initialize user-defined information. */ err_struct err_s = {" ", " "}; /* Declare the database. */ EXEC SQL DECLARE ALIAS FILENAME 'personnel'; /* Register the first error handling routine. */ sql_register_error_handler(txn_error_handler,0); /* Store the address of the currently registered pointer in a variable. */ sql_get_error_handler(&rtn_ptr, &err_struct_ptr); printf("Please enter the Job Code (or EXIT):\n"); scanf(" %s", j_code); release_screen = getchar(); while (((strcmp(j_code,"exit")) != 0) && ((strcmp(j_code,"EXIT")) != 0)) { printf("Enter the Wage Class: ", w_class); scanf(" %s", w_class); release_screen = getchar(); while (((strcmp(w_class,"1")) != 0) && ((strcmp(w_class,"2")) !=0) && ((strcmp(w_class,"3")) !=0) && ((strcmp(w_class,"4")) !=0)) { printf("Please enter one of the following values for Wage Class:\n"); printf(" 1 2 3 4\n"); scanf(" %s", w_class); release_screen = getchar(); } printf("Please enter the Job Title: \n"); scanf(" %s", j_title); release_screen = getchar(); /* Start a transaction. */ EXEC SQL SET TRANSACTION READ WRITE NOWAIT RESERVING JOBS FOR EXCLUSIVE WRITE; /* Register the second error handling routine. */ sql_register_error_handler(dupl_error_handler, &err_s); /* Store information in a structure for use by the error handling routine. */ strcpy(err_s.sql_proc_name, "INSERT_JOBS"); strcpy(err_s.sql_col_value, j_code); EXEC SQL INSERT INTO JOBS (JOB_CODE, WAGE_CLASS, JOB_TITLE) VALUES (:j_code, :w_class, :j_title ); if (SQLCA.SQLCODE == SQLCODE_SUCCESS) EXEC SQL COMMIT; else EXEC SQL ROLLBACK; /* Deregister the error handling routine. */ sql_deregister_error_handler(); printf("Please enter the Job Code (or EXIT):\n"); scanf(" %s", j_code); release_screen = getchar(); /* Register the txn_error_handler routine again. Use the address stored in * rtn_ptr. */ sql_register_error_handler(rtn_ptr, 0); } return; }