Symfoware Server アプリケーション開発ガイド(埋込みSQL編) - FUJITSU - |
目次 索引 |
付録A C言語のサンプルプログラム |
コールバック機能の利用例を以下に示します。
SQL文の実行時間が5秒以上であった場合、または、SQL文の実行エラーが発生した場合に、出口コールバック関数を使用して、標準出力に情報を出力します。
コールバック関数を動的ライブラリを使用して登録しています。
シングルスレッド環境で動作するアプリケーションでコールバック関数を使用して登録しています。
上記のコールバック関数と実行結果を以下に示します。
コールバック関数 dynscb.c
/* libdynscb.so */ #include<stdio.h> #include<sys/time.h> #include"sqlrdbei.h" /* コールバック関数の動的登録関数宣言 */ /* コールバック関数のプロトタイプ */ SQLRETURN CFEntry1( SQLHDBS, char *, char *, void *, SQLCALL_T * ); SQLRETURN CFEntry2( SQLHDBS, char *, char *, void *, SQLCALL_T * ); struct timeval start_tv,end_tv; /* コールバック関数の動的登録 */ SQLRETURN SQLDynSetCallback( SQLHDBS sid ) { SQLRETURN ret; short kind_list[14]; /* コールバック関数の登録 */ kind_list[0] = (short)SQLRDB_CF_SELECT; kind_list[1] = (short)SQLRDB_CF_DELETE_SEARCH; kind_list[2] = (short)SQLRDB_CF_UPDATE_SEARCH; kind_list[3] = (short)SQLRDB_CF_DELETE_POSITION; kind_list[4] = (short)SQLRDB_CF_UPDATE_POSITION; kind_list[5] = (short)SQLRDB_CF_INSERT; kind_list[6] = (short)SQLRDB_CF_OPEN; kind_list[7] = (short)SQLRDB_CF_FETCH; kind_list[8] = (short)SQLRDB_CF_CLOSE; kind_list[9] = (short)SQLRDB_CF_CALL; kind_list[10] = (short)SQLRDB_CF_COMMIT; kind_list[11] = (short)SQLRDB_CF_CONNECT; kind_list[12] = (short)SQLRDB_CF_DISCONNECT; kind_list[13] = 0; ret = SQLSetCallback(sid,CFEntry1,NULL,kind_list,SQLRDB_CALL_IN); if( ret != SQLRDB_NORMAL ){ return( ret ); } ret = SQLSetCallback(sid,CFEntry2,NULL,kind_list,SQLRDB_CALL_OUT); if( ret != SQLRDB_NORMAL){ return( ret ); } return( SQLRDB_NORMAL); } /* 入口コールバック関数 CFEntry1 */ SQLRETURN CFEntry1(SQLHDBS sid, char *SQLSTATE, char *SQLMSG, void *user_area, SQLCALL_T *SQLDATA) { /* 開始時刻の取得 */ gettimeofday(&start_tv,NULL); return(SQLRDB_CONTINUE); } /* 出口コールバック関数 CFEntry2 */ SQLRETURN CFEntry2(SQLHDBS sid, char *SQLSTATE, char *SQLMSG, void *user_area, SQLCALL_T *SQLDATA) { long exec_sec,exec_usec; /* 終了時刻の取得 */ gettimeofday(&end_tv,NULL); /* 実行時間の計算 */ exec_sec = end_tv.tv_sec - start_tv.tv_sec; exec_usec = end_tv.tv_usec - start_tv.tv_usec; if(exec_usec<0){ exec_sec--; exec_usec += 1000000; } /* エラーが発生した場合 */ if((memcmp(SQLSTATE,"00",2)!=0) && (memcmp(SQLSTATE,"01",2)!=0) && (memcmp(SQLSTATE,"02",2)!=0)){ printf("<<ERROR>>\n"); printf("APPLICATION: %s\n" , SQLDATA->application); printf("LINE : %ld\n", SQLDATA->sql_line); printf("SQL : %s\n" , SQLDATA->sql_stmt); if(SQLMSG != NULL){ printf("SQLSTATE : %s\n" , SQLSTATE); printf("SQLMSG : %s\n" , SQLMSG); } printf("EXEC TIME : %ld.%06ld\n" , exec_sec , exec_usec); printf("\n"); } /* 実行時間が5秒以上であった場合 */ else if(exec_sec >= 5){ printf("<<TIME-OVER>>\n"); printf("APPLICATION: %s\n" , SQLDATA->application); printf("LINE : %ld\n", SQLDATA->sql_line); printf("SQL : %s\n" , SQLDATA->sql_stmt); printf("EXEC TIME : %ld.%06ld\n" , exec_sec , exec_usec); printf("\n"); } return(SQLRDB_CONTINUE); } |
実行結果
<<ERROR>> APPLICATION: sample LINE : 17 SQL : UPDATE SCHEMA1.TABLE1 SET COL01=1,COL02=2 WHERE COL01=1 SQLSTATE : 40001 SQLMSG : JYP2099E デッドロックが発生しました. EXEC_TIME : 0.000121 <<TIME-OVER>> APPLICATION: sample LINE : 23 SQL : DELETE FROM SCHEMA1.TABLE1 WHERE COL01<10 EXEC_TIME : 6.000239 |
コールバック関数 dynscb.c
/* dynscb.dll */ #include<stdio.h> #include<windows.h> #include"sqlrdbei.h" /* コールバック関数の動的登録関数宣言 */ /* コールバック関数のプロトタイプ */ SQLRETURN CFEntry1( SQLHDBS, char *, char *, void *, SQLCALL_T *); SQLRETURN CFEntry2( SQLHDBS, char *, char *, void *, SQLCALL_T *); unsigned long start_tv,end_tv; /* コールバック関数の動的登録 */ SQLRETURN SQLDynSetCallback( SQLHDBS sid ) { SQLRETURN ret; short kind_list[14]; /* コールバック関数の登録 */ kind_list[0] = (short)SQLRDB_CF_SELECT; kind_list[1] = (short)SQLRDB_CF_DELETE_SEARCH; kind_list[2] = (short)SQLRDB_CF_UPDATE_SEARCH; kind_list[3] = (short)SQLRDB_CF_DELETE_POSITION; kind_list[4] = (short)SQLRDB_CF_UPDATE_POSITION; kind_list[5] = (short)SQLRDB_CF_INSERT; kind_list[6] = (short)SQLRDB_CF_OPEN; kind_list[7] = (short)SQLRDB_CF_FETCH; kind_list[8] = (short)SQLRDB_CF_CLOSE; kind_list[9] = (short)SQLRDB_CF_CALL; kind_list[10] = (short)SQLRDB_CF_COMMIT; kind_list[11] = (short)SQLRDB_CF_CONNECT; kind_list[12] = (short)SQLRDB_CF_DISCONNECT; kind_list[13] = 0; ret = SQLSetCallback(sid,CFEntry1,NULL,kind_list,SQLRDB_CALL_IN); if( ret != SQLRDB_NORMAL){ return( ret ); } ret = SQLSetCallback(sid,CFEntry2,NULL,kind_list,SQLRDB_CALL_OUT); if( ret != SQLRDB_NORMAL){ return( ret ); } return( SQLRDB_NORMAL ); } /* 入口コールバック関数 CFEntry1 */ SQLRETURN CFEntry1(SQLHDBS sid, char *SQLSTATE, char *SQLMSG, void *user_area, SQLCALL_T *SQLDATA) { /* 開始時刻の取得 */ start_tv = GetTickCount(); return(SQLRDB_CONTINUE); } /* 出口コールバック関数 CFEntry2 */ SQLRETURN CFEntry2(SQLHDBS sid, char *SQLSTATE, char *SQLMSG, void *user_area, SQLCALL_T *SQLDATA) { long exec_sec,exec_msec; /* 終了時刻の取得 */ end_tv = GetTickCount(); /* 実行時間の計算 */ exec_sec = (end_tv-start_tv)/1000; exec_msec= (end_tv-start_tv)%1000; /* エラーが発生した場合 */ if((memcmp(SQLSTATE,"00",2)!=0) && (memcmp(SQLSTATE,"01",2)!=0) && (memcmp(SQLSTATE,"02",2)!=0)){ printf("<<ERROR>>\n"); printf("APPLICATION:%s\n" , SQLDATA->application); printf("LINE :%ld\n" , SQLDATA->sql_line); printf("SQL :%s\n" , SQLDATA->sql_stmt); if(SQLMSG != NULL){ printf("SQLSTATE : %s\n" , SQLSTATE); printf("SQLMSG : %s\n" , SQLMSG); } printf("EXEC TIME :%ld.%03ld\n" , exec_sec , exec_msec); printf("\n"); } /* 実行時間が5秒以上かかった場合 */ else if(exec_sec >=5){ printf("<<TIME-OVER>>\n"); printf("APPLICATION: %s\n" , SQLDATA->application); printf("LINE : %ld\n", SQLDATA->sql_line); printf("SQL : %s\n" , SQLDATA->sql_stmt); printf("EXEC TIME : %ld.%03ld\n" , exec_sec , exec_msec); printf("\n"); } return(SQLRDB_CONTINUE); } |
実行結果
<<ERROR>> APPLICATION: sample LINE : 17 SQL : UPDATE SCHEMA1.TABLE1 SET COL01=1,COL02=2 WHERE COL01=1 SQLSTATE : 40001 SQLMSG : JYP2099E デッドロックが発生しました. EXEC_TIME : 0.078 <<TIME-OVER>> APPLICATION: sample LINE : 23 SQL : DELETE FROM SCHEMA1.TABLE1 WHERE COL01<10; EXEC_TIME : 13.125 |
目次 索引 |