DESCRIBE
DESCRIBE ステートメントは、準備済みステートメントに関する情報の入手に使用します。
準備済みステートメントの説明については、PREPAREを参照してください。
呼び出し
このステートメントは、アプリケーション・プログラム、SQL 関数、 SQL プロシージャー、またはトリガー内にのみ組み込むことができます。 これは実行可能ステートメントですが、動的に準備することはできません。Java™ では指定できません。
権限
権限は不要です。準備済みステートメントを作成するために必要な権限については、PREPAREを参照してください。
構文
.-OUTPUT-. >>-DESCRIBE--+--------+--statement-name-------------------------> .-SQL-. .-LOCAL--. >--+-USING--+-----+--DESCRIPTOR--+--------+--SQL-descriptor-name-+->< | '-GLOBAL-' | '-INTO----descriptor-name----+-------------------------+------' '-USING--+-NAMES--------+-' +-SYSTEM NAMES-+ +-LABELS-------+ +-ANY----------+ +-BOTH---------+ '-ALL----------'
説明
- statement-name
- 準備済みステートメントを識別します。DESCRIBE ステートメントが実行される時点で、この名前は
アプリケーション・サーバー側で準備済みステートメントを識別していなければなりません。
準備済みステートメントが全選択または VALUES INTO ステートメントの場合は、結果表の列の記述が情報として返されます。準備済みステートメントが CALL ステートメントの場合は、プロシージャーの OUT および INOUT パラメーターの記述が情報として戻されます。
- USING
- SQL 記述子を識別します。
- LOCAL
- 記述子の名前の有効範囲はプログラム呼び出しのローカルであることを指定します。
- GLOBAL
- 記述子の名前の有効範囲は SQL セッション全体であることを指定します。
- SQL-descriptor-name
- SQL 記述子の名前を指定します。名前は、指定の有効範囲を持つ既存の記述子を識別するものでなければなりません。
SQL 記述子に入る情報の説明については、GET DESCRIPTORを参照してください。
- INTO descriptor-name
-
SQL 記述子域 (SQLDA) を指定します。これについては、SQLDA (SQL 記述子域)で説明しています。DESCRIBE ステートメントを実行する前に、SQLDA の以下の変数をセットしておく必要があります。
- SQLN
- SQLDA で用意される SQLVAR 項目の数を指定します。 DESCRIBE ステートメントを実行する前に、SQLN にゼロ以上の値をセットしておく必要があります。 必要なオカレンスの数を決定する手法については、必要な SQLVAR オカレンスの数の決定を参照してください。
DESCRIBE ステートメントが実行されると、データベース・マネージャーでは、SQLDA の各変数に次のような値を割り当てます。
- SQLDAID
- 最初の 6 バイトは 'SQLDA ' (つまり、5 文字の後にスペース文字) に設定
されます。
7 番目のバイトは、記述された結果列に基づいて設定されます。
- SQLDA の各項目 (または、結果表の列) に 2 つ、3 つ、または 4 つの SQLVAR 項目が入って いる場合、この 7 番目のバイトはそれぞれ '2'、'3'、または '4' に設定されます。 この技法は、LOB または特殊タイプ結果列、ラベル、およびシステム名に対応するために 使用されています。
- それ以外の場合、7 番目のバイトはスペース文字に設定されます。
SQLDA 内にすべての結果列の記述を含める余地がない場合、7 番目のバイトはスペ ース文字に設定されます。
8 番目のバイトはスペース文字に設定されます。
- SQLDABC
- SQLDA の長さ (バイト)。
- SQLD
- 準備済みステートメントが SELECT の場合、SQLD は、その結果表の列の数に拡張 SQLVAR 項目の数を足したものに設定されます。 拡張 SQLVAR 項目については、SQLVAR のオカレンスのフィールドの説明を参照してください。準備済みステートメントが CALL ステートメントの場合、SQLD はプロシージャーの OUT および INOUT パラメーターの数に設定されます。 準備済みステートメントが VALUES INTO の場合、SQLD は VALUES 節にある式の数 に拡張 SQLVAR 項目の数を加えたものに設定されます。 これら以外の場合、SQLD は 0 に設定されます。
- SQLVAR
- SQLD の値が 0 の場合、または SQLD の値が SQLN の値より大きい場合は、SQLVAR のオカレンスには値が割り当てられません。
SQLD の値が n (n は 0 より 大きいが、SQLN の値以下) の場合、SQLVAR の最初から n 番目までのオカレンスには、 SQLVAR の最初のオカレンスに結果表の最初の列 (または、パラメーターまたは VALUES 節内 の式) の記述が入り、SQLVAR の 2 番目のオカレンス に結果表の 2 番目の列 (または、パラメーターまたは VALUES 節内の 式) の記述が入り、以下同様に、値が割り当てられます。SQLVAR オカレンスに割り当てられる値については、SQLVAR のオカレンスのフィールドの説明を参照してください。
- USING
- SQLDA のそれぞれの SQLNAME 変数に、どのような値を割り当てるかを
指定します。要求した値が存在しない場合、または名前の長さが 30 より大きい場合は、SQLNAME の長さは 0 にセットされます。
- NAMES
- 列 (またはパラメーター) の名前を割り当てます。これはデフォルトです。選択リストに 名前が明示的にリストされている準備済みステートメントについての DESCRIBE の場合、指定されたその名前が戻されます。戻される列名は大/小文字の区別があり、区切り文字はありません。
- SYSTEM NAMES
- 列のシステム列名を割り当てます。
- LABELS
- 列のラベルを割り当てます。(列のラベルは、LABEL ステートメントによって定義されます。) ラベルの最初の 20 バイトだけが戻されます。
- ANY
- 列のラベルを割り当てます。列にラベルがない場合は、代わりに列の名前が割り当てられます。
- BOTH
- 列のラベルと名前の両方を割り当てます。この場合、追加情報に応じ るために、1 つの列ごとに SQLVAR の 2 つから 3 つのオカレンスが必要になり ますが、その数は、結果セットに特殊タイプが入っているか否かによって決 まります。この拡張の SQLVAR 配列を指定するには、SQLN を 2*n か 3*n (この場合の n は、表やビュー内の列数) に設定します。 SQLVAR の最初の n 個のオカレンスには、列の名前が入り、 2 番目または 3 番目の n オカレンスには、列のラベルが含まれます。 特殊タイプがない場合、SQLVAR 項目の 2 番目のセットにそのラベルが戻されます。 それ以外の場合、ラベルは、SQLVAR 項目の 3 番目のセット内に戻されます。
- ALL
- ラベル、列名、およびシステム列名を割り当てます。この場合、追加情報に応じるために、 1 つの列ごとに SQLVAR の 3 つから 4 つのオカレンスが必要になりますが、その数は、 結果セットに特殊タイプが入っているか否かによって決まります。この拡張の SQLVAR 配列を指定するには、SQLN を 3*n か 4*n (この場合の n は、結果表内の列数) に設定します。 SQLVAR の最初の n オカレンスには、システム列名が入ります。 2 番目または 3 番目の n オカレンスには、列のラベルが含まれます。 列名がシステム列名とは異なる場合、列名は 3 番目または 4 番目の n オカレンスに含まれます。 その他の場合、SQLNAME フィールドは長さゼロに設定されます。 特殊タイプが指定されていない場合、ラベルは、SQLVAR 記入項目の 2 番目のセット内に戻され、 列名は、SQLVAR 記入項目の 3 番目のセット内に戻されます。 それ以外の場合、ラベルは、SQLVAR 記入項目の 3 番目のセット内に戻され、列名は、 SQLVAR 記入項目の 4 番目のセット内に戻されます。
注
PREPARE INTO: 準備済みステートメントに関する情報は、PREPARE ステートメントの INTO 文節を使用しても入手することができます。
SQL 記述子の割り振り: DESCRIBE ステートメントを実行する前に、ALLOCATE DESCRIPTOR ステートメントを使用して SQL 記述子を割り振らなければなりません。 割り振られた記述子項目の数が結果列の数よりも小さい場合、警告 (SQLSTATE 01005) が戻されます。
SQLDA の割り振り: C、COBOL、PL/I、および RPG では、 DESCRIBE または PREPARE INTO ステートメントが実行される前に、 十分なストレージをいくつかの SQLVAR オカレンスに割り当てる必要があります。SQLN は、割り当てられた SQLVAR オカレンスの数に設定されなければなりません。 準備済み SELECT ステートメントの結果表にある列の記述を入手する場合は、 SQLVAR 項目のオカレンスの数を、結果表にある列の数以上にしなければなりません。 さらに、列に LOB や特殊タイプを指定している場合は、SQLVAR 項目のオカレンス数として、 列数の 2 倍の数値を指定する必要があります。詳しくは、必要な SQLVAR オカレンスの数の決定を参照してください。 SQLDA を割り振るための可能な方法としては、 以下の 3 通りがあります。
- 最初の技法
- アプリケーションで処理する必要があるどの選択リストにも対応できるように、SQLVAR 項目のオカレンス数を十分にとって SQLDA を割り振ります。
極端なことをいえば、SQLVAR の数を、結果表で許容されている列の最大数の 2 倍にすることも可能です。
いったん割り振りが終了すれば、アプリケーションでは、この SQLDA を繰り返し使用することができます。
この方法は、大量の記憶域を使用します。また、ある特定の選択リストで、その記憶域のごく一部しか使用しないとしても、記憶域の割り振りが解除されることはありません。
- 2 番目の技法
- 選択リストを処理するたびに、以下の 3 つのステップを繰り返し実行します。
- SQLVAR 項目のオカレンスがない SQLDA、つまり SQLN がゼロの SQLDA を使用して、 DESCRIBE ステートメントを実行します。 SQLD に戻される値は、SQLVAR 項目のオカレンスの必要数か、結果列の数です。 SQLVAR 項目がないため、警告が出されます。1
- SQLDAID フィールドの第 7 バイトがブランクでない場合は、SQLDA を (SQLDAID の第 7 バイトの値) * SQLD オカレンス数で割り振り、新規の SQLDA の SQLN を (SQLDAID の第 7 バイトの値) * SQLD に設定します。そうでない場合、SQLDA を SQLD オカレンスで割り振り、新規の SQLDA の SQLN を SQLD の値に設定します。
- 次に、この新しい SQLDA を使用して、再び DESCRIBE ステートメントを実行します。
この方法をとると、方法 1 より記憶域管理が向上しますが、DESCRIBE ステートメントの数が 2 倍になります。
- 3 番目の技法
- 選択リストの大半 (ほとんど全部) を扱うのに十分な範囲で、なるべく小さな SQLDA を割り振ります。
SQLDA が小さ過ぎることが原因で、DESCRIBE ステートメントの実行に失敗した場合は、より大きな SQLDA を割り振って、再び DESCRIBE ステートメントを実行します。
新しい SQLDA では、最初の DESCRIBE の実行で SQLD に戻された値 (または SQLD の 2 倍の値) を使用して、
SQLVAR 項目のオカレンス数を指定してください。
この方法は、方法 1 と方法 2 を組み合わせたものです。方法 3 の効果は、最初の SQLDA のサイズを適切に選定できるかどうかによって左右されます。
暗黙的な非表示列に関する考慮事項: DESCRIBE OUTPUT ステートメントから暗黙的な非表示列に関する情報が返されるのは、照会を記述するときに、照会の最終的な結果表の SELECT リストの一部として、暗黙的な非表示列と定義されている基本表の列を組み込むことを明示的に指定した場合に限られます。 暗黙的な非表示列が照会の結果表の一部でない場合、その照会に関する情報を 戻す DESCRIBE OUTPUT ステートメントにはどの暗黙的な非表示列に関する情報も含まれていません。
例
C プログラムの中で、SQLVAR 項目のオカレンスなしの SQLDA を使用して DESCRIBE ステートメントを実行します。 SQLD がゼロより大きければ、その値を使用して、SQLVAR 項目に必要なオカレンス数を指定した SQLDA を割り振ります。その後で、新しい SQLDA を使用して DESCRIBE ステートメントを実行します。
EXEC SQL BEGIN DECLARE SECTION;
char stmt1_str [200];
EXEC SQL END DECLARE SECTION;
EXEC SQL INCLUDE SQLDA;
struct sqlda initialsqlda;
struct sqlda *sqldaPtr;
EXEC SQL DECLARE DYN_CURSOR CURSOR FOR STMT1_NAME;
… /* code to prompt user for a query, then to generate */
/* a select-statement in the stmt1_str */
EXEC SQL PREPARE STMT1_NAME FROM :stmt1_str;
… /* code to set SQLN to zero and to allocate the SQLDA */
EXEC SQL DESCRIBE STMT1_NAME INTO :initialsqlda;
if (initialsqlda.sqld == 0); /* statement is a select-statement */
{
… /* Code to allocate correct size SQLDA (sets sqldaPtr) */
if (strcmp(SQLSTATE,"01005") == 0)
{
sqldaPtr->sqln = 2*initialsqlda.sqld;
SETSQLDOUBLED(sqldaPtr, SQLDOUBLED);
}
else
{
sqldaPtr->sqln = initialsqlda.sqld;
SETSQLDOUBLED(sqldaPtr, SQLSINGLED);
}
EXEC SQL DESCRIBE STMT1_NAME INTO :*sqldaPtr;
… /* code to prepare for the use of the SQLDA */
EXEC SQL OPEN DYN_CURSOR;
… /* loop to fetch rows from result table */
EXEC SQL FETCH DYN_CURSOR USING DESCRIPTOR :*sqldaPtr;
…
}
…