2009-07-24 31 views
15

スクリプトに使用されるテーブル名を変数に設定するpl \ sqlスクリプトがあります。そこで、私はウェブ上で見つけたいくつかの例から、私は以下のコードを書いた。最初のセクションが機能するので、私の一般的な構文は正しいと思うが、テーブル名に変数を使用しようとする2番目のセクション( "SQLエラー:ORA-00903:無効なテーブル名")。テーブル名にoracleスクリプトの変数を使用する方法

私が間違っていることを知っている人は誰でも知っています...私は多分PL \ SQLを多用していないので、おそらく私はちょっとしたことが分かりません。

--works 
variable numOfrecords number; 
exec :numOfrecords := 10; 
select * from customers2008 where rownum < :numOfrecords; 

--does not work 
variable tableNm CHAR; 
exec :tableNm := 'customers2008'; 
print tableNm; 
select * from :tableNm; 
+1

FYI:実際の例に基づいて、PL/SQLを実際に使用しているわけではありません。私はあなたがSQLPlusスクリプトを持っていることを意味すると思います。技術的には、execコマンドはPL/SQLを呼び出していますが、ここで示しているのはSQLPlusコマンドです。 –

+1

まあ、技術的に彼は両方を使用しています - スクリプトの変数コマンドはPL/SQLバインド変数を宣言します。 –

答えて

6

Substitution variables作品:

SQL> select * from &table_name; 
Enter value for table_name: dual 
old 1: select * from &table_name 
new 1: select * from dual 

D 
- 
X 
+0

ハァッ!偉大な心は似ていると思っています - ドクのリンクさえも同じです。 –

+0

確かに!リンクはアンカーと同じです:) –

14

あなたは(ケースになりそうだもの)SQLPLUSからこのスクリプトを実行している場合は、DEFINEコマンドを使用したい、あなたはSQLPLUS substition変数を作成することができます

define tableNm = 'customers2008' 
select * from &tableNm; 

参照Using Sql*Plusこれらを使用する方法の詳細について:それはちょうどまっすぐ文字列置換、例えばあります。あなたは、このような事前に定義された位置substition変数、使用して、コマンドラインからスクリプトに値を渡すことができます。

define tableNm = &1 
select * from &tableNm; 

を...そしてそのようSQLPLUSを起動します。そうしないと

sqlplus user/[email protected] @myscript.sql customers2008 

コマンドライン上の値を渡すと、スクリプト呼び出し者は値の入力を求められます。

バインド変数と置換変数の違いについては、下記のDave Costaの答えを参照してください。

+0

SQLPlusの呼び出しの例が(少なくとも私にとっては)うまくいかないというのはちょっとした不安です。コマンドラインで値を渡すには、スクリプトを呼び出す必要があります(例: 'sqlplus user/pwd @ server @myscript customers2008'です。 –

+0

本当に!編集され、修正されました。 –

+0

それを気に入ってください!素晴らしいものSteve! – CFNinja

8

いくつかの説明を追加しようとするには、次の

バインド変数と呼ばれ、使用しようとしていた方法を。バインド変数は、Oracle SQLでコロンとそれに続く識別子で識別されます。バインド変数の目的は、SQL文の解析時にその値を知る必要がないことです。ステートメントは一度解析され、変数にバインドされた異なる値で複数回実行されます。

SQL文を解析するには、関係する表名と列名を認識する必要があります。そのため、テーブル名はバインド変数では表現できません。これは、解析時に値がわからないためです。

SQLとインラインPL/SQlをSQLPlus経由で実行している場合は、置換変数を使用すると簡単にこの問題に対処できます。置換変数は、SQLPlusクライアントがコマンドを読み取った後、解析のためにOracleに送信する前にその値に置き換えられます。 Oracleは、テーブルのバインド変数(または他のオブジェクト名)を許可していないため

EXECUTE IMMEDIATE 'select * from' || tableNm; 

これは、次のとおりです。

7

あなたはこのような何かをしなければなりません。

EXECUTE IMMEDIATEアプローチでは、tableNmの値がユーザによって指定された場合には、SQL injectionの攻撃が広く発生しています。

関連する問題