方法4の必要条件を学習する前に、選択リスト項目とプレースホルダという用語を理解する必要があります。選択リスト項目とは、問合せ内でキーワードSELECTの後に続く列または式のことです。たとえば、次の動的問合せは3つの選択リスト項目を含んでいます。
SELECT ename, job, sal + comm FROM emp WHERE deptno = 20
プレースホルダとは、SQL文の中で実際のバインド変数用に場所を確保する、ダミーのバインド変数のことです。宣言する必要はなく、任意の名前を付けられます。
バインド変数のプレースホルダはSET句、VALUES句およびWHERE句で最もよく使用されます。たとえば、次の動的SQL文はそれぞれ2つのプレースホルダを含んでいます。
INSERT INTO emp (empno, deptno) VALUES (:e, :d) DELETE FROM dept WHERE deptno = :num OR loc = :loc
Pro*C/C++プリコンパイラでは、すべての実行可能な動的SQL文についてOracleコールが生成されます。動的SQL文に選択リスト項目またはプレースホルダが指定されていない場合、Oracleにはその文を実行するための補足情報は必要ありません。次のDELETE文がこのカテゴリに該当します。
DELETE FROM emp WHERE deptno = 30
ただし、ほとんどの動的SQL文には、次のUPDATE文のように、選択リスト項目、またはバインド変数のプレースホルダが含まれています。
UPDATE文:
UPDATE emp SET comm = :c WHERE empno = :e
バインド変数のためのプレースホルダまたは選択リスト項目を含む動的SQL文を実行するには、入力(バインド)値および問合せを実行するときにFETCHされた値を保持するプログラム変数についての情報が必要です。Oracleは次の情報を必要とします。
バインド変数の数と選択リスト項目の数
各バインド変数と選択リスト項目の長さ
各バインド変数と選択リスト項目のデータ型
各バインド変数のアドレスと、各選択リスト項目の値が設定される出力変数のアドレス
選択リスト項目またはバインド変数のプレースホルダについてOracleで必要な情報は、その値以外はすべて、SQL記述子領域(SQLDA)というプログラム・データ構造体に格納されます。SQLDA構造体はsqlda.h
ヘッダー・ファイルに定義されています。
選択リスト項目の記述は選択記述子に格納されます。また、バインド変数に対するプレースホルダの記述はバインド記述子に格納されます。
選択リスト項目の値は出力変数に格納され、バインド変数の値は入力変数に格納されます。これらの変数のアドレスを選択SQLDAまたはバインドSQLDAに格納すると、出力値を書き込む位置および入力値を読み込む位置がOracleに認識されます。
値はどのようにしてこれらのデータ変数に格納されるのでしょうか。出力値は、カーソルを使用してFETCHされます。入力値は、通常はユーザーが対話形式で入力した情報をもとに、プログラムによって代入されます。
バインド記述子および選択記述子は、通常はポインタによって参照されます。動的SQLプログラムでは、少なくとも1つのバインド記述子と1つの選択記述子のポインタを次のように宣言する必要があります。
#include <sqlda.h> ... SQLDA *bind_dp; SQLDA *select_dp;
この後にSQLSQLDAAlloc()
関数を使用すると、次のように記述子を割り当てることができます。
bind_dp = SQLSQLDAAlloc(runtime_context, size, name_length, ind_name_length);
Oracle8以前のバージョンでは、SQLSQLDAAlloc()はsqlaldt()に相当します。
定数SQL_SINGLE_RCTX
は、(dvoid*)0
として定義されます。これは、アプリケーションがシングル・スレッドの場合に、runtime_contextに使用します。
DESCRIBE文を使用すると、Oracleに必要な情報が得られます。
DESCRIBE SELECT LIST文は、各選択リスト項目を検査して名前とその長さを判断します。次にこの情報を使用できるように選択SQLDAに格納します。たとえば、格納された情報は、後で印刷出力の列見出しとして選択リスト名を使用するときなどに使用できます。選択リスト項目の合計数も、DESCRIBE文によりSQLDAに格納されます。
DESCRIBE BIND VARIABLES文は、各プレースホルダを調べて、その名前および長さを確認した後、それらの情報を入力バッファおよびバインドSQLDAに格納します。格納された情報は、後でプレースホルダ名を使用してバインド変数の値の入力をユーザーに求めるときなどに使用できます。