Symfoware(R) Server RDBユーザーズガイド 応用プログラム開発編 - FUJITSU -
目次 索引 前ページ次ページ

上へ第2章 データベースを処理する応用プログラムの開発の概要
上へ2.1 SQL埋込みCプログラムの作成方法

2.1.8 ポインタ変数として宣言したホスト変数の使用方法

ここでは、ポインタ変数として宣言したホスト変数の使用方法について、以下を説明します。

■ポインタ変数のデータ領域の設定とサイ

ポインタ変数は、領域のアドレスを保持する変数です。ポインタ変数を利用すると、動的に領域を獲得することができます。また、関数のパラメタで領域のアドレスを渡すことができるため、応用プログラム間で領域を共有できます。

ホスト変数をポインタ変数として宣言した場合、ホスト変数はデータではなくデータ領域の先頭アドレスを保持します。したがって、応用プログラム中で、最初にホスト変数を使用する前に、参照するデータ領域のアドレスを設定してください。

ポインタ変数が参照するデータ領域のサイズは、翻訳時または実行時に、以下のように認識されます。

◆数値型の場合

数値型の場合、ポインタ変数が参照する領域のサイズは参照する先の数値型のサイズになります。数値型については、“SQLリファレンスガイド”を参照してください。

◆文字列型の場合

文字列型のポインタ変数が参照する領域のサイズは、先頭アドレスからナル文字までの長さとなります。

文字列型のポインタ変数を値指定に使用する場合、参照先のデータ領域に設定した文字列の最後にナル文字を設定する必要があります。

EXEC  SQL  BEGIN  DECLARE  SECTION;
char     *country;                                            (1)
         :
EXEC  SQL  END  DECLARE  SECTION;
         :
country = malloc(11);                                         (2)
strcpy( country, "Japanese" );                              (3)
EXEC SQL INSERT INTO SCH.TBL( COUNTRY )                       (4)
    VALUES( :country );
(1) 文字列型のポインタ変数countryを宣言します。
(2) countryに11バイトの領域のアドレスを設定します。
(3) countryの参照する領域に文字列を設定します。strcpy関数を使用して、文字列の最後にナル文字を設定します。
(4) INSERT文の値指定にcountryを指定します。

文字列型のポインタ変数を相手指定に使用する場合、参照先のデータ領域の最後にナル文字を設定します。Symfowareは先頭アドレスからナル文字までを領域のサイズとします。

 

EXEC  SQL  BEGIN  DECLARE  SECTION;
char         *country;                                      (1)
        :
EXEC  SQL  END  DECLARE  SECTION;
        :
country = malloc(11);                                        (2)
memset( country, ' ', 10 );                                (3)
*(country+10) = '\0';                                      (4)
EXEC SQL SELECT COUNTRY INTO :country                        (5)
    FROM SCH.TBL
    WHERE DATANO = 1;
(1) 文字列型のポインタ変数countryを宣言します。
(2) countryに11バイトの領域のアドレスを取得します。
(3) 領域の値は不定なので、空白文字を設定します。
(4) 11バイト目にナル文字を設定します。
(5) 単一行SELECT文の相手指定にcountryを指定します。

◆可変長文字列型の場合

可変長文字列型の場合は翻訳時に構造体に変換されるため、データ領域はデータ長に2バイト足したサイズが必要になります。可変長文字列型のサイズは、変換された構造体のメンバ sqllen に設定してください。

応用プログラム中に以下のように宣言します。

VARCHAR    *country;

            ↓翻訳時に構造体に変換します。

    struct country_SQLVAR {
        short        sqllen;
        char        sqlvar[1];
    } *country;

可変長文字列型のポインタ変数を相手指定に使用する場合、SQL文を実行するとデータ領域長を設定するメンバ sqllen に取得したデータの長さが設定されます。したがって、再度SQL文を実行する場合は、実行前に領域長を設定し直す必要があります。

 

EXEC SQL BEGIN DECLARE SECTION;
    VARCHAR        *country;
    short          loop;
EXEC SQL END DECLARE SECTION;
char        buff[12];
         :
country = (struct country_SQLVAR *)malloc(13);                (1)
country->sqllen = 10;                                        (2)

for ( loop=0; loop<MAX_COUNTRY; loop++ ) {                   (3)
    EXEC SQL SELECT COUNTRY INTO :country                    (4)
    FROM SCH.TBL
    WHERE DATANO = :loop;
           :
    country->sqllen = 10;                                    (5)
}
           :
(1) countryに13バイトの領域のアドレスを設定します。
(2) 変換後の構造体のメンバsqllenに領域長を設定します。
(3) MAX_COUNTRY件のデータを取り出します。
(4) countryを指定したSELECT文を実行します。
(5) 次のSQL文の実行前に、変換後の構造体のメンバsqllenに領域長を設定します。

◆BLOB型の場合

BLOB型の場合は翻訳時に構造体に変換されるため、データ領域はデータ長に8バイト足したサイズが必要になります。また、データ領域は1Kバイト(1024バイト)単位で取得してください。BLOB型のサイズは、変換された構造体のメンバ ホスト変数名_length に設定してください。

応用プログラム中に以下のように宣言します。

SQL TYPE IS BLOB    *image;

            ↓翻訳時に構造体に変換します。

    struct image_SQLBLOB {
        long        image_reserced;
        long        image_length;
        char        image_data[1];
    } *image;

BLOB型のポインタ変数を相手指定に使用する場合、SQL文を実行するとデータ領域長を設定するメンバ 変数名_length に取得したデータの長さが設定されます。したがって、再度SQL文を実行する場合は、実行前に領域長を設定し直す必要があります。

EXEC SQL BEGIN DECLARE SECTION;
    SQL TYPE IS BLOB        *image;
    short                   loop;
EXEC SQL END DECLARE SECTION;
char        buff[12];
        :
image = (struct image_SQLBLOB *)malloc(10248);                (1)
image->image_length = 10240;                                 (2)

for ( loop=0; loop<MAX_COUNTRY; loop++ ) {                    (3)
    EXEC SQL SELECT COUNTRY INTO :image                       (4)
    FROM SCH.TBL
    WHERE DATANO = :loop;
           :
    image->image_length = 10240;                             (5)
}
           :
(1) imageに10248バイトの領域のアドレスを設定します。
(2) 変換後の構造体のメンバimage_lengthに領域長を設定します。
(3) MAX_COUNTRY件のデータを取り出します。
(4) imageを指定したSELECT文を実行します。
(5) 次のSQL文の実行前に、変換後のメンバimage_lengthに領域長を設定します。

◆ROW_ID型の場合

ROW_ID型の場合、ポインタ変数が参照する領域は24バイト必要です。また、サイズは24になります。

◆DECIMAL型の場合

精度が p のDECIMAL型の場合、ポインタ変数が参照する領域は (p÷2)+1 バイト必要です。また、サイズも(p÷2)+1になります。

◆NUMERIC型の場合

精度が p のNUMERIC型の場合、ポインタ変数が参照する領域は p+1 バイト必要です。また、サイズも p+1 になります。

◆構造体型の場合

構造体型の場合、ポインタ変数が参照する領域のサイズは各メンバのサイズの合計となります。

◆SQLSTATEの場合

SQLSTATEをポインタ宣言する場合は、5バイト以上の領域が必要です。

■ポインタ変数の使用方

以下に、ポインタ変数を使用したデータ操作の概要を示します。また、このデータ操作を実現するためのプログラミング例を示します。

image

(1) 従業員データベース“DB01”の存在するサーバに接続します。

(2) 従業員番号をホスト変数に対話で入力します。

(3) 入力された従業員番号を元に、従業員の氏名、所属、勤続年数を検索します。

(4) 従業員のデータを表示します。

(5) 従業員データベース“DB01”の存在するサーバとのコネクションを切断します。

◆データ領域を動的に取得する例

EXEC SQL BEGIN DECLARE SECTION;
    char    SQLSTATE[6];
    char    SQLMSG[256];
            :
    short   datano;
    SQL TYPE IS BLOB    *image;
            :
EXEC SQL END DECLARE SECTION;

short main()
{
            :
    image = (struct image_SQLBLOB *)malloc( 10240 + 8 );       …… (1)
    image->image_length = 10240;
    datano = 5;
            :
    /* データの取得 */
    EXEC SQL SELECT IMAGE                                    …… (2)
            INTO :image
            FROM SCH01.TBL01
            WHERE DATANO = :datano;
            :
    return 1;
}

(1) ホスト変数 image に領域のアドレスを設定します。

(2) 該当するデータを取得します。

◆関数パラメタをデータ領域として使用する例

/* データ取得関数 */
short get_data( void *, short );

short main()
{
            :
    void    *image;
            :
    image = malloc( 10240 + 8 );                              …… (1)
            :
    ret = get_data( image, 5 );                               …… (2)
            :
    return 1;
}

short get_data(
    void    *image_data;
    short   number;
{
EXEC SQL BEGIN DECLARE SECTION;
    char    SQLSTATE[6];
    char    SQLMSG[256];
            :
    SQL TYPE IS BLOB    *image;
    short   datano;
            :
EXEC SQL END DECLARE SECTION;
            :
    image = (struct image_SQLBLOB *)image_data;              …… (3)
    image->image_length = 10240;                            …… (4)
    datano = number;
            :
    /* データの取得 */
    EXEC SQL SELECT IMAGE                                    …… (5)
            INTO :image
            FROM SCH01.TBL01
            WHERE DATANO = :datano;
            :
    return 0;
}

(1) データ取得関数に指定するデータ領域を取得します。

(2) データ取得関数を呼び出します。

(3) ホスト変数に領域アドレスを設定します。

(4) ホスト変数の領域長を設定します。

(5) データを取得します。


目次 索引 前ページ次ページ

All Rights Reserved, Copyright (C) 富士通株式会社 2003-2004