根本的な原因
Oracleには、3種類のSQLステートメントがあります(さらに、PL / SQLブロックがあります):
- データ定義言語(DDL)のステートメント。これらのステートメントは、データベースの構造を変更します。それらは通常、動詞「ALTER」または「CREATE」で始まります
- データ変更言語(DML)のステートメント。各テーブルの構造を変更せずに、テーブル内のコンテンツを変更するステートメントがあります。これらのステートメントは通常、「INSERT」、「MERGE」、または「DELETE」で始まります。
- 私が「クエリ言語」と呼んでいるステートメント(これらの正規名はないようです)。このステートメントは、動詞「SELECT」で始まります。
Oracleのバインド変数は、DMLおよびクエリステートメントの一部の特別な場所でのみ許可されます。許可されていない場所でバインド変数を使用しようとしています。したがって、エラーです。
ソリューション
バインド変数なしでステートメントを作成します。文字列連結を使用する代わりに、完全なクエリ文字列を作成します。
文字列を連結する前に入力をサニタイズする場合は、DBMS_ASSERTパッケージを使用してください。
背景
バインド変数は、Oracleが変数の値を知らなくてもクエリプランを作成できる場合にのみ使用できます。 DDLステートメントの場合、クエリプランはありません。したがって、バインド変数は許可されていません。
DMLおよびクエリステートメントでは、バインド変数は、タプル内で使用される場合(基礎となる集合論に関して)、つまり、値がテーブル内の値と比較される場合、または値がテーブルに挿入される場合にのみ許可されます。 。実行プランの構造を変更することは許可されていません(たとえば、ターゲットテーブルを変更したり、比較の数を変更したりすることはできません)。