ページの先頭行へ戻る
Symfoware Server V10.0.0/V10.0.1 アプリケーション開発ガイド(埋込みSQL編)

A.11 コールバック機能の利用例

コールバック機能の利用例を以下に示します。

SQL文の実行時間が5秒以上であった場合、または、SQL文の実行エラーが発生した場合に、出口コールバック関数を使用して、標準出力に情報を出力します。

上記のコールバック関数と実行結果を以下に示します。

SolarisLinuxコールバック関数 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

Windowsコールバック関数 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