ヘッダーをスキップ

Oracle Rdb SQLリファレンス・マニュアル リリース7.2 E06178-01 |
| 目次 | 索引

戻る | 次へ |

# 付録D
SQL動的記述子領域（SQLDAおよびSQLDA2）

SQL記述子領域（SQLDA）は、動的SQLプログラムでのみ使用されるパラメータのコレクションです。SQLでは、SQLDAおよびSQLDA2の2つの記述子領域を備えています。D.6〜D.6.2項ではSQLDA2固有の情報について説明します。

動的SQLでは、プリコンパイルされたプログラムのソース・コードまたはSQLモジュール言語プロシージャの一部であるSQL文とは対照的に、プログラムは実行時にSQL文を受け入れたり生成できます。プリコンパイルされたSQLまたはSQLモジュール言語文とは異なり、動的に実行されるこのようなSQL文は、必ずしもプログラムのソース・コードの一部ではありませんが、プログラムの実行中に生成できます。動的SQLは、プログラムが処理する必要のあるSQL文のタイプを予測できない場合に便利です。

SQLDAを使用するには、ホスト言語がポインタ変数をサポートする必要があります。ポインタ変数では、変数に直接データを格納するのではなくデータのアドレスを格納することによって記憶域に間接的にアクセスします。ポインタ変数のサポートも行うSQLプリコンパイラによってサポートされる言語は、PL/I、C、BASICおよびAdaです。ポインタ変数をサポートするその他の言語はSQLDAを使用できますが、ソース・コードに直接SQL文を埋め込むのではなく、SQL文を含むSQLモジュール・プロシージャをコールする必要があります。

# D.1 SQLDAの目的

SQLDAでは、動的SQL文の情報をプログラムに、そのプログラムによって割り当てられたメモリーの情報をSQLに提供します。具体的には、SQLおよびホスト言語プログラムは次の目的でSQLDAを使用します。

- SQLでは、準備された文のパラメータ・マーカーおよび選択リスト項目の情報を書き込む場所としてSQLDAを使用します。SQLでは、PREPARE...SELECT LIST INTO文またはDESCRIBE文を処理する場合に、入出力パラメータ・マーカーの数およびデータ型、およびSQLDAに対する選択リスト項目の情報を書き込みます。
  パラメータ・マーカーとは疑問符（?）であり、PREPARE文の文字列にあるパラメータを表します。SQLは、パラメータ内の値、または動的SQL文の実行時は動的メモリーにパラメータ・マーカーを置き換えます。
  DESCRIBE文は、準備されたSELECT文にある選択リスト項目の情報をSQLDAに書き込むため、ホスト言語プログラムはそれに記憶域（パラメータまたは動的メモリー）を割り当てることができます。プログラムによって割り当てられた記憶域は、後続のFETCH文で、準備されたSELECT文の結果表の行にある値を受け取ります。
  ある時点で、SQLDAには入出力パラメータ・マーカーまたは選択リスト項目のいずれかの情報が含まれますが、両方は含まれません。

  - SQLは、DESCRIBE...SELECT LIST文またはPREPARE...SELECT LIST文の実行時に、選択リスト項目の情報をSQLDAに書き込みます。

  - SQLは、DESCRIBE...MARKERS文の実行時に、パラメータ・マーカーの情報をSQLDAに書き込みます。準備された文にパラメータ・マーカーがない場合、DESCRIBE...MARKERS文はSQLDAに値を挿入してパラメータ・マーカーがないことを示します。

- プログラムでは、準備された文の、選択リスト項目または入出力パラメータ・マーカーについてSQLがSQLDAに書き込んだ情報を読み取る場所としてSQLDAを使用します。

  - DESCRIBE...SELECT LIST文またはDESCRIBE...MARKERS文の後、プログラムは選択リスト項目またはパラメータ・マーカーの数およびデータ型を読み取ります。
    プログラムでは、その情報を使用して、パラメータ・マーカーまたは選択リスト項目に相当する値に対して（パラメータを宣言するか動的メモリーを割り当てて）記憶域を割り当てます。

- プログラムでは、パラメータ・マーカーまたは選択リスト項目に割り当てた記憶域のアドレスを書き込む場所としてSQLDAを使用します。

- SQLでは、パラメータ・マーカーまたは選択リスト項目の情報を読み取る場所としてSQLDAを使用します。

  - OPEN文では、SQLは準備されたSELECT文のパラメータ・マーカーのアドレスを読み取り、処理するプログラム用にカーソルを設定します。

  - FETCH文では、SQLは準備されたSELECT文の選択リスト項目のアドレスを読み取るため、プログラムによって割り当てられた記憶域にフェッチ対象の行の値を書き込むことができます。

  - EXECUTE文では、SQLはSELECT文以外の準備された文のパラメータ・マーカーのアドレスを読み取ります。

  SQLDAからの情報を読み取る場合に使用されたOPEN文およびFETCH文自体は、PREPARE文で使用された動的文でもなければ、OPEN文およびFETCH文で指定されたカーソルを宣言するDECLARE CURSOR文でもありません。これらの文では準備された文を使用しますが、それ自体は準備された文にはならないSQL文です。動的に実行できない文のリストは、「PREPARE文」を参照してください。

# D.2 SQLおよびプログラムによるSQLDAの使用方法

SQLDAを使用する操作の具体的な順序は、プログラムが許容できるのが動的に生成されたSELECT文のみか、SELECT以外の文のみか、あるいはその両方かによって異なります。次に説明する順序は、通常SQLDAを使用する際にプログラムが実行する手順です。具体的な例は、『Oracle Rdb7 Guide to SQL Programming』の動的SQLの使用に関する章、およびサンプル・ディレクトリでのOracle Rdbのインストール時に作成したサンプル・プログラムを参照してください。

1. プログラムは埋込みSQL文INCLUDE SQLDAを使用して自動的にSQLDAを宣言します。また、プログラムはSQLDA用にメモリーを割り当て、そのいずれかのフィールドの値SQLNを設定する必要があります。SQLNの値には、SQLDAに情報を格納できるパラメータ・マーカーまたは選択リスト項目の最大数を指定します。
   プログラムで複数のSQLDAを使用できますが、SQLDA以外の名前で追加のSQLDA構造体を明示的に宣言する必要があります。SELECT文とSELECT以外の文を両方受入れ可能な動的SQLプログラムでは、2つのSQLDAを宣言すると便利な場合があります。一方のSQLDAでパラメータ・マーカーの情報を格納し、もう一方で選択リスト項目の情報を格納します。（そのようなプログラムでの複数のSQLDA構造体宣言の代替手段は、プログラムがSQLDAでのパラメータ・マーカー情報を使用して終了した後、追加のESCRIBE...SELECT LIST文を発行することです。）
   SQLDAの宣言および割当てを実行するのは1回のみにする必要があります。残りの手順は、プログラムが持つ処理対象の動的SQL文の数繰り返します。

2. SQLでは、準備された文の、選択リスト項目（DESCRIBE...SELECT LIST文の場合）またはパラメータ・マーカー（DESCRIBE...MARKERS文の場合）の数およびデータ型をSQLDAに書き込みます。SQLは、選択リスト項目またはパラメータ・マーカーの数をSQLDAのSQLDフィールドに指定し、SQLTYPEフィールドにそのデータ型を表すコードを格納します。

3. 特定の準備された文がSELECT文かどうかをプログラムで判断する必要がある場合、DESCRIBE...SELECT LIST文の後のSQLCA.SQLERRD配列の第2要素の値を読み取ります。その値が1の場合、準備された文はSELECT文であり、後のFETCH文の実行時に生成された行に対してプログラムで記憶域を割り当てる必要があります。

4. SQL文でパラメータ・マーカーを使用するときは、パラメータのデータ型に関して仮定を設けないでください。SQLで、特定の操作により適したデータ型にパラメータを変換する場合があります。たとえば、LIKE条件にある値式としてパラメータ・マーカーを使用すると、SQLではもう1つの値式にCHARデータ型がある場合でも、そのパラメータにVARCHARデータ型を返します。STARTING WITH条件およびCONTAINING条件は、同様にパラメータ・マーカーを処理します。明示的にSQLDAのSQLTYPEフィールドをCHARに設定することによって、そのような条件のVARCHARデータ型をオーバーライドできます。

5. プログラムは、SQLDAから、選択リスト項目の数、データ型および長さ（DESCRIBE...SELECT LIST文の後）またはパラメータ・マーカー（DESCRIBE...MARKERS文の後）の情報を読み取ります。次に、各選択リスト項目またはパラメータに対して記憶域（パラメータまたは動的メモリー）を割り当て、その記憶域のアドレスをSQLDAに書き込みます。プログラムでは、SQLDAのSQLDATAフィールドにアドレスを指定します。
   プログラミング言語によってサポートされていないパラメータ・マーカーまたは選択リスト項目のデータ型をSQLが使用する場合、プログラムでは適切なデータ型および長さにSQLTYPEおよびSQLLENフィールドを変換する必要があります。プログラムは、SQLによってDESCRIBE文から返されるSQLTYPEおよびSQLLENの値を、SQLとホスト言語の両方がサポートするデータ型および長さに変更します。

6. プログラムは、パラメータ・マーカーに代入される値を指定し、それらの値を割り当てられた記憶域に書き込みます。

7. SQLはSQLDAのパラメータ・マーカーの情報を読み取ります。

   - 準備された文がSELECT文である場合、SQLは、SQLDAを参照するOPEN文の実行時に、準備されたSELECT文のパラメータ・マーカーのアドレスを読み取ります。

   - 文がその他の準備された文である場合、SQLは、SQLDAを参照するEXECUTE文の実行時に、その文のパラメータ・マーカーのアドレスを読み取ります。

   SQLは、パラメータ・マーカーのアドレスを使用して記憶域の値（プログラムで指定）を取得し、準備された文でパラメータ・マーカーに代入します。

8. 最後に、準備されたSELECT文専用に、SQLは、SQLDAを参照するFETCH文の実行時に、選択リスト項目のアドレスを読み取ります。SQLではその情報を使用して結果表の行の値をメモリーに書き込みます。

# D.3 SQLDAの宣言

プログラムでは次の方法でSQLDAを宣言できます。

- プリコンパイルするAda、CまたはPL/Iプログラムに埋め込まれたINCLUDE SQLDA文を使用して行います。INCLUDE SQLDA文では、プログラムのプリコンパイル時に、SQLDAと呼ばれるSQLDA構造体の宣言がプログラムに自動的に挿入されます。

- プリコンパイルされたAdaプログラムでは、SQL定義パッケージにSQLDA_ACCESSタイプを指定して行います。SQLDA_ACCESSを指定すると、複数の宣言で使用して複数のSQLDA構造体を宣言できるため、埋込みINCLUDE SQLDA文よりも利点があります。

- プリコンパイルされたCプログラムおよびCホスト言語プログラムでは、sql_sqlda.hヘッダー・ファイルを使用できます。次の例は、Cプログラムにファイルを組み込む方法を示しています。

      #include <sql_sqlda.h>

  sql_sqlda.hヘッダー・ファイルは、SQL_T_SQLDA（またはSQL_T_SQLDA2）データ型を定義するSQLDA構造体用にtypedef文を組み込みます。また、SQLDA構造体の定義に対するスーパーセットとしてSQL_T_SQLDA_FULL（またはSQL_T_SQLDA2_FULL）データ型を定義します。SQL_T_SQLDA_FULLデータ型は、レイアウトではSQL_T_SQLDAデータ型と同じです。ただし、CALL文の記述時にSQLが使用する追加フィールドのある追加共用体を含む点が異なります。
  SQLDA構造体の宣言の詳細は、『Oracle Rdb7 Guide to SQL Programming』を参照してください。

- ポインタ変数をサポートするホスト言語で記述されたプログラムでSQLDAを明示的に宣言して行います。そのようなホスト言語は、SQLプリコンパイラによってサポートされていない場合でも、動的SQLを利用できます。プリコンパイラによってサポートされていない言語は、ホスト言語のソース・コードに直接SQL文を埋め込むかわりに、SQL文を含むSQLモジュール言語プロシージャをコールして動的SQLを使用する必要があります。SQLモジュール言語の詳細は、第3章を参照してください。
  （プリコンパイラによるサポートの有無に関係なく）SQLDA構造体を明示的に宣言するプログラムは、SQLDA構造体の名前を指定しますが、その名前はSQLDAでも他の有効な名前でも構いません。SELECT文とSELECT以外の文を両方受入れ可能な動的SQLプログラムでは、2つのSQLDAを宣言すると便利な場合があります。一方のSQLDAでパラメータ・マーカーの情報を格納し、もう一方で選択リスト項目の情報を格納します。

SQLDAは常に4つのフィールドを含んでおり、5番目のフィールドを含んでいる場合もあります。5番目のフィールドSQLVARは繰返しフィールドです。C以外の言語の場合、個々の選択リスト項目を示す5つのパラメータ、または準備された文のパラメータ・マーカーで構成されます。C言語の場合は、6つのパラメータで構成されます。

次の例は、複数のホスト言語でのSQLDAの宣言を示しています。PL/I、CおよびAdaについては、INCLUDE SQLDA文を含むプログラムを処理する場合に、SQLで挿入される宣言の例を示します。BASICについては、明示的にSQLDAを宣言する場合にプログラムで使用される形式の例を示しています。

これらの宣言例ではすべて、SQLDA構造体の名前としてSQLDAの名前を使用していますが、プログラムでは有効であればどのような名前でも使用できます。

例D-1は、INCLUDE SQLDA文を含むCプログラムを処理する場合に、SQLで挿入される宣言を示しています。

例D-1 AdaでのSQLDAの宣言
    type SQLNAME_REC is
        record
            NAME_LEN : standard.short_integer;
            NAME_STR : standard.string (1..30);
        end record;

    type SQLVAR_REC is
        record
            SQLTYPE : standard.short_integer;
            SQLLEN : standard.short_integer;
            SQLDATA : system.address;
            SQLIND : system.address;
            SQLNAME : sqlname_rec;
        end record;
    type SQLVAR_ARRAY is array (1..255) of sqlvar_rec;

    type SQLDA_RECORD;
    type SQLDA_ACCESS is access SQLDA_RECORD;
    type SQLDA_RECORD is
        record
            SQLDAID : standard.string (1..8) := 'SQLDA   ';
            SQLDABC : standard.integer;
            SQLN : standard.short_integer;
            SQLD : standard.short_integer;
            SQLVAR : sqlvar_array;
        end record;

例D-2は、BASICプログラムでSQLDAを明示的に宣言する場合に使用される形式を示しています。

例D-2 BASICでのSQLDAの宣言
    RECORD  SQLDA_REC
       string SQLDAID = 8
       long SQLDABC
       word SQLN              ! Program must explicitly
       word SQLD              ! set SQLN equal to the number
       GROUP SQLVAR(100)      ! of occurrences of SQLVAR
          word SQLTYPE
          word SQLLEN
          long SQLDATA
          long SQLIND
          GROUP SQLNAME
             word SQLNAME
             string SQLNAMEC = 30
          END GROUP SQLNAME
       END GROUP SQLVAR
    END RECORD SQLDA_REC

    DECLARE SQLDA_REC SQLDA

例D-3は、INCLUDE SQLDA文を含むCプログラムを処理する場合に、SQLで挿入される宣言を示しています。

例D-3 CでのSQLDAの宣言
    struct SQLDA_STRUCT {
              char SQLDAID[8];
              int SQLDABC;
              short SQLN;
              short SQLD;
              struct SQLVAR_STRUCT {
                short SQLTYPE;
                short SQLLEN;
                char *SQLDATA;
                short *SQLIND;
                short SQLNAME_LEN;
                char SQLNAME[30];
                   } SQLVAR[1];
              } *SQLDA;

例D-4は、INCLUDE SQLDA文を含むPL/Iプログラムを処理する場合に、SQLで挿入される宣言を示しています。

例D-4 PL/IでのSQLDAの宣言
    /*
        EXEC SQL INCLUDE SQLDA;
    */
    DCL 1 SQLDA BASED ( SQLDAPTR ),
         2 SQLDAID  CHAR(8),
         2 SQLDABC  BIN FIXED(31),
         2 SQLN  BIN FIXED(15),
         2 SQLD  BIN FIXED(15),
         2 SQLVAR  (SQLSIZE REFER(SQLN)),
          3 SQLTYPE  BIN FIXED(15),
          3 SQLLEN  BIN FIXED(15),
          3 SQLDATA  PTR,
          3 SQLIND  PTR,
          3 SQLNAME  CHAR(30) VAR;
    DCL SQLSIZE BIN FIXED;
    DCL SQLDAPTR PTR;

# D.4 SQLDAでのフィールドの説明

表D-1は、SQLDAの様々なフィールドと、SQLによるその使用方法について説明しています。ある時点で、SQLDAには選択リスト項目またはパラメータ・マーカーのいずれかの情報が含まれますが、両方は含まれません。

表D-1 SQLDAのフィールド
フィールド名 | フィールドの意味 | 設定元 | 使用先
--- | --- | --- | ---
SQLDAID | 値が常に文字列SQLDAである文字列フィールド。 | SQL | 使用しない。
SQLDABC | SQLDAのバイト長であり、SQLNのファンクション（SQLDABC = 16+ (44 * SQLN)）。 | SQL | 使用しない。
SQLN | SQLVARグループ・フィールドの合計出現数（この値はSQLD、またはDESCRIBE、PREPARE OUTPUT INTO文の値以上であること）。ランタイム・エラーが生成される。 | プログラム | プログラムのSQLDAに十分な記憶域が割り当てられているかどうかを判断するSQL。
SQLD | 準備された文の出力項目（DESCRIBE...OUTPUTの場合）またはパラメータ・マーカー（DESCRIBE...INPUTの場合）数（ない場合は、値は0になる）。 | SQL | 記憶域を割り当てる入力パラメータまたは出力パラメータの数を決定するプログラム。
SQLVAR | それぞれの発生が選択リスト項目またはパラメータ・マーカーを示す、繰返しグループ・フィールド（SQLDの値が0の場合は使用しない）。 | 値なし | 次のエントリでサブフィールドの説明を参照。
SQLVARサブフィールド（各選択リスト項目またはパラメータ・マーカーで1回出現）:
フィールド名 | フィールドの意味 | 設定元 | 使用先
SQLTYPE | 値が選択リスト項目またはパラメータ・マーカーのデータ型を示す、SQLVARのサブフィールド（表D-2を参照）。 | SQL | 記憶域を該当するデータ型のパラメータに合せて割り当てるプログラム。
SQLLEN | 値が選択リスト項目またはパラメータ・マーカーの長さ（バイト）を示す、SQLVARのサブフィールド。 CHAR1およびCHARACTER VARYINGR1については、長さフィールドのオーバーヘッドなしで宣言されたデータの長さを示す。 固定長データ型（TINYINT、SMALLINT、INTEGER、BIGINT、およびDECIMAL）については、SQLLENを半分に分割。 TINYINT、SMALLINT、INTEGERおよびBIGINTの場合、SQLLENの下位バイトは長さ、上位バイトはスケール（小数点以下桁数）を示す。 | プログラムがリセットされるまではSQL（ユーザーのみが設定可能なDECIMALまたはH_FLOATは除く） | 選択リスト項目またはパラメータ・マーカーに、適切なサイズの記憶域を割り当てるプログラム。
| DECIMALについては、下位バイトは精度、上位バイトはスケールを示す。ただし、DECIMALデータ型のSQLLENはユーザーのみ設定可能のため、DESCRIBE文ではSQLから返されない。 |  |
| リスト・カーソルでは、スケール変更係数を必要とするデータ型でデータが返されない。 |  |
| 浮動小数点データ型については、SQLLENはバイト数のフィールド長を示す。したがって、SQLLEN = 4はREALデータ型、SQLLEN = 8はDOUBLE PRECISIONデータ型、SQLLEN = 16はH_FLOATデータ型をそれぞれ示す。データの浮動小数点表現（VAXとIEEE）は、SQL$PREコマンドラインの/FLOAT修飾子で決定される。 |  |
SQLDATA | 値が選択リスト項目またはパラメータ・マーカーに割り当てられた記憶域のアドレスである、SQLVARのサブフィールド。 CHARACTER VARYING2の場合、長さフィールドの許可に十分なメモリー（SQLLENに2オクテットを加えたもの）を割り当てる。 | プログラム | SQL: EXECUTE文およびOPEN文で、プログラムで格納された値を取得し、それを準備された文でパラメータ・マーカーに代入する。 FETCH文で、結果表の値を格納する。
SQLIND | 値がワード（16ビット）・サイズの、標識変数のアドレスである、SQLVARのサブフィールド（プログラムでSQLINDを設定しない場合の値は0）。 | プログラム | プログラムまたはSQL: FETCH文で、SQLによって選択リスト項目に関連付けられる標識変数の値を格納する。 FETCH文の後に、プログラムによって、選択リスト項目に関連する標識変数の値を取得する。 EXECUTE文およびOPEN文で、SQLによってパラメータ・マーカーに関連する標識変数の値を取得する。
SQLNAME1 | 値が次のようなSQLVARの可変文字列サブフィールド: 出力項目に対する、準備されたSELECT文の選択リストの列の名前。 入力項目に対する、パラメータ・マーカーが（INSERT文またはUPDATE文で）割り当てられた、または（基本条件で）比較された列の名前。 選択リスト項目、割当てまたは比較で、演算式または基本条件以外の条件に関連する場合、SQLではSQLNAMEに値が割り当てられない。 | SQL | 選択リスト項目またはパラメータ・マーカーに関連付けられた列名を検索するためのプログラム（オプション）。

1CHARACTER、NATIONAL CHARACTERを含みます。
2VARCHAR、VARCHAR2、NATIONAL CHARACTER、VARYING、RAWおよびLONG VARCHARを含みます。
3SQLNAMEフィールドは最大30バイト長です。SQLでは列名に使用できるのは最大31文字です。31文字の列名は、SQLによりSQLNAMEに格納されると30文字に切り捨てられます。フルネームの長さを表示するには、SQLLDA2を使用します。

表D-2は、SQLVARのSQLTYPEサブフィールドの数値およびリテラル値とその値の意味を説明しています。

表D-2 SQLDAおよびSQLDA2のSQLTYPEフィールドのSQLTYPEに対するコード
数値 | リテラル値 | データ型
--- | --- | ---
449 | SQLDA_VARCHAR | VARCHAR1、CHARACTER VARYING
453 | SQLDA_CHAR | CHAR、CHARACTER
481 | SQLDA_FLOAT | FLOAT5、REAL、DOUBLE PRECISION
485 | SQLDA_DECIMAL | DECIMAL
497 | SQLDA_INTEGER | INTEGER
501 | SQLDA_SMALLINT | SMALLINT
503 | SQLDA_DATE | DATE VMS
505 | SQLDA_QUADWORD | BIGINT
507 | SQLDA_ASCIZ | ASCIZ2
509 | SQLDA_SEGSTRING | LIST OF BYTE VARYING
515 | SQLDA_TINYINT | TINYINT
516 | SQLDA_VARBYTE | VARBYTE3、4
519 | SQLDA2_DATETIME | 日時（ANSI）
521 | SQLDA2_INTERVAL | INTERVAL

1SQLDA2構造体の場合、このデータ型にはロングワードの長さ接頭辞があります。
2ASCIZに対するSQLTYPEコードはDESCRIBE文によってSQLDAに返されませんが、返されるデータ型のオーバーライドに使用できます。
3このデータ型の値はリスト要素のフェッチに対してのみ有効です。
4このデータ型ではNULL値は許容されません。
5浮動小数点数に対してSQLが仮定する浮動小数点表現は、SQL$MODコマンドラインまたはSQL$PREコマンドラインの/FLOAT修飾子で決まります。