この項では、動的SQL文の定義に使用できる4つの方法を紹介します。まずそれぞれの方法の機能および制限事項を簡単に説明した後、適切な方法を選択するためのガイドラインを示します。その後の項では、これらの方法の使用方法について説明します。また、このマニュアルの各ホスト言語の補足資料には、サンプル・プログラムが記載されています。
この4つの方法は番号が大きくなるに従って対象が広がるようになっています。つまり方法2は方法1を包含し、方法3は方法1と方法2を包含するというようになります。ただし、表10-1に示すように、それぞれの方法は、特定の種類のSQL文の処理に適しています。
表10-1 動的SQLの使用方法の適用性
方法 | SQL文の種類 |
---|---|
1 |
入力ホスト変数のない非問合せ |
2 |
入力ホスト変数の数がわかっている非問合せ |
3 |
選択リスト項目の数および入力ホスト変数の数がわかっている問合せ |
4 |
選択リストの項目の数または入力ホスト変数の数が不明な問合せ |
選択リスト項目には、列名や式を使用します。
この方法では、動的SQL文を受け入れるかまたは作成し、 EXECUTE
IMMEDIATE
コマンドを使用してその文をすぐに実行できます。このSQL文では、問合せ(SELECT
文)の使用や、入力ホスト変数に対するプレースホルダの組込みはできません。たとえば、次のホスト文字列は有効です。
'DELETE FROM EMP WHERE DEPTNO = 20' 'GRANT SELECT ON EMP TO scott'
方法1では、SQL文が実行のたびに解析されます(HOLD_CURSOR
=YES
と指定した場合を除く)。
この方法を使用すると、プログラムは動的SQL文を受け入れ(または作成し)、PREPARE
およびEXECUTE
コマンドを使用してその文を処理します。SQL文は、問合せにはできません。プリコンパイル時に、入力ホスト変数のプレースホルダの数および入力ホスト変数のデータ型を明確にする必要があります。たとえば、次のホスト文字列はこのカテゴリに入ります。
'INSERT INTO EMP (ENAME, JOB) VALUES (:emp_name, :job_title)' 'DELETE FROM EMP WHERE EMPNO = :emp_number'
方法2では、SQL文の解析は1回しか行われませんが(RELEASE_CURSOR
=YES
と指定している場合を除く)、ホスト変数に異なる値を指定すれば、複数回実行できます。SQLデータ定義文(CREATE
など)は、PREPARE
の際に実行されます。
この方法を使用すると、プログラムは動的問合せを受け入れるか、または作成し、DECLARE
、OPEN
、FETCH
およびCLOSE
カーソル・コマンドとともにPREPAREコマンドを使用してその問合せを処理します。プリコンパイル時に、選択リストの項目数、入力ホスト変数のプレース・ホルダ数および入力ホスト変数のデータ型がわかっている必要があります。たとえば、次のホスト文字列は有効です。
'SELECT DEPTNO, MIN(SAL), MAX(SAL) FROM EMP GROUP BY DEPTNO' 'SELECT ENAME, EMPNO FROM EMP WHERE DEPTNO = :dept_number'
この方法を使用すると、プログラムは動的SQL文を受け入れるか、または作成し、記述子(「方法4の使用方法」を参照)を使用してその文を処理します。選択リストの項目数、入力ホスト変数のプレース・ホルダー数および入力ホスト変数のデータ型は、実行時まで不明でもかまいません。たとえば、次のホスト文字列はこのカテゴリに入ります。
'INSERT INTO EMP (<unknown>) VALUES (<unknown>)' 'SELECT <unknown> FROM EMP WHERE DEPTNO = 20'
方法4は、選択リスト項目の数または入力ホスト変数の数が不明な動的SQL文を実行するときに必要です。
4つの方法はどれも、動的SQL文を文字列に格納する必要があり、この文字列は、ホスト変数または引用符で囲んだリテラルであることが必要です。SQL文を文字列に格納する場合は、キーワードEXEC SQLおよび文の終了記号は省略してください。
方法2および方法3では、プリコンパイル時に入力ホスト変数のプレース・ホルダ数および入力ホスト変数のデータ型がわかっている必要があります。
方法の番号が大きくなるほどアプリケーションへの制約は少なくなりますが、コードの記述が難しくなります。通常は、最も簡単な方法を使用してください。ただし、動的SQL文を繰り返し実行する場合、方法1では実行のたびに再解析されるので、これを避けるために方法2を使用してください。
方法4は最も柔軟性に富んでいますが、複雑なコード記述方法および動的SQLの概念の完全な理解が求められます。通常、方法4を使用するのは、方法1、2または3を使用できない場合のみです。図10-1の決定論理を参考にして、適切な方法を選択してください。
動的SQL文を文字配列に格納する場合は、その配列に空白を埋め込んでからSQL文を格納してください。こうして余分な文字を消去します。別のSQL文を格納するために配列を再利用するときに、この処理が重要となります。一般に、SQL文を格納する前には必ずホスト文字列を初期化(または再初期化)してください。
ホスト文字列にはヌル終端文字を使用しないでください。OracleではNULL終了文字は文字列の終了マーカーとはみなされません。SQL文の一部として扱われます。
VARCHAR
変数を使用して動的SQL文を格納する場合、VARCHAR
の長さが正しく設定(または再設定)されていること確認してから、PREPARE文またはEXECUTE
IMMEDIATE
文を実行してください。
EXECUTE
を実行すると、SQLCA内のSQLWARN警告フラグはリセットされます。したがって、無条件の更新(WHERE
句の省略により発生)などの誤りを検出するには、PREPARE
文を実行してからEXECUTE
文を実行するまでの間にSQLWARNフラグをチェックしてください。