方法4の実装は、言語によって非常に異なります。したがって、この項では概要のみを説明します。詳細は、使用するホスト言語の補足資料を参照してください。
方法3を使用したプログラムでも処理できない種類の動的SQL文があります。選択リストの項目数または入力ホスト変数のプレースホルダの数が実行時までわからない場合は、プログラムで記述子を使用する必要があります。記述子とは、プログラムおよびOracleによって動的SQL文内の変数の完全な記述を保存するために使用されるメモリー領域です。
複数行の問合せの場合、宣言済の出力ホスト変数のリストに選択した列値をFETCH
INTO
したことを思い出してください。この選択リストがわからない場合は、プリコンパイル時にINTO
句でホスト変数リストを作成できません。たとえば、次の問合せでは2つの列値が戻されます。
SELECT ENAME, EMPNO FROM EMP WHERE DEPTNO = :dept_number;
ただし、この選択リストをユーザーに定義させると、その問合せによって戻される列の数はわからなくなります。
この種の動的問合せを処理するには、プログラムでDESCRIBE
SELECT
LIST
コマンドを発行し、SQL記述子領域(SQLDA)というデータ構造体を宣言する必要があります。この構造体は、問合せ選択リストの列の記述を保存するため、選択記述子とも呼ばれます。
同様に、動的SQL文に含まれる入力ホスト変数のプレースホルダの数がわからない場合には、プリコンパイル時にUSING
句によってホスト変数リストを作成できません。
このような動的SQL文を処理するには、プログラムでDESCRIBE
BIND
VARIABLES
コマンドを発行し、入力ホスト変数のプレースホルダの説明を保存するために、バインド記述子という別の種類のSQLDAを宣言する必要があります。(入力ホスト変数はバインド変数とも呼ばれます。)
プログラムにアクティブSQL文が複数ある(たとえば、複数のカーソルをOPENしている)場合、それぞれの文には専用のSQLDAが必要になります。ただし、非並行のカーソルではSQLDAを再利用できます。なお、1つのプログラム内のSQLDAの数に制限はありません。
DESCRIBEは、選択リストまたは入力ホスト変数の説明を保存するために記述子を初期化します。
選択記述子を指定すると、DESCRIBE
SELECT
LIST
文によってPREPARE
された動的問合せ内の各選択リスト項目が調べられ、その名前、データ型、制約、長さ、位取りおよび精度が確認されます。その後、この情報は選択記述子に格納されます。
バインド記述子を指定すると、DESCRIBE
BIND
VARIABLES
文によってPREPARE
された動的SQL文の各プレースホルダが調べられ、その名前および長さ、関連付けられた入力ホスト変数のデータ型が確認されます。続いて、この情報がそのバインド記述子に格納されます。たとえば、プレースホルダ名を使用して、ユーザーに入力ホスト変数の値の入力を要求できます。
SQLDAとは、選択リスト項目または入力ホスト変数の記述を保存するホストプログラムのデータ構造体です。
SQLDA変数は、宣言部で定義されません。
SQLDAはホスト言語によって異なりますが、一般的な選択SQLDAには、問合せ選択リストに関する次の情報が格納されています。
記述できる列の最大数
記述により検出された列の実際の数
列値を格納するバッファのアドレス
列値の長さ
列値のデータ型
インジケータ変数の値のアドレス
列名を格納するバッファのアドレス
列名を格納するバッファのサイズ
列名の現行の長さ
一般的なバインドSQLDAには、SQL文内の入力ホスト変数に関する次の情報が格納されています。
記述できるプレースホルダの最大数
記述で検出されたプレースホルダの実際の数
入力ホスト変数のアドレス
入力ホスト変数の長さ
入力ホスト変数のデータ型
インディケータ変数のアドレス
プレースホルダ名を格納するバッファのアドレス
プレースホルダ名を格納するバッファのサイズ
プレースホルダ名の現在の長さ
インディケータ変数名を格納するバッファのアドレス
インディケータ変数名を格納するバッファのサイズ
インディケータ変数名の現行の長さ
特定のホスト言語のSQLDA構造体および変数の名前を調べるには、使用するホスト言語の補足資料を参照してください。
方法4では、一般に次の順序で埋込みSQL文を使用します。
EXEC SQL PREPARE statement_name FROM { :host_string | string_literal }; EXEC SQL DECLARE cursor_name CURSOR FOR statement_name; EXEC SQL DESCRIBE BIND VARIABLES FOR statement_name INTO bind_descriptor_name; EXEC SQL OPEN cursor_name [USING DESCRIPTOR bind_descriptor_name]; EXEC SQL DESCRIBE [SELECT LIST FOR] statement_name INTO select_descriptor_name; EXEC SQL FETCH cursor_name USING DESCRIPTOR select_descriptor_name; EXEC SQL CLOSE cursor_name;
選択記述子およびバインド記述子の両方を使用する必要はありません。問合せ選択リスト内の列数がわかっていて、入力ホスト変数のプレースホルダの数がわからない場合、方法4のOPEN
文と次に示す方法3のFETCH
文を併用できます。
EXEC SQL FETCH emp_cursor INTO host_variable_list;
逆に、入力ホスト変数のプレースホルダの数がわかっていて、選択リストの列数がわからない場合は、次の方法3のOPEN
文と方法4のFETCH
文を併用できます。
EXEC SQL OPEN cursor_name [USING host_variable_list];
方法4では、問合せ以外の文にEXECUTE
を使用できるので注意してください。
これらの文によりプログラムで記述子を使用して動的SQL文をどのように処理できるかについては、使用するホスト言語の補足資料を参照してください。