テキストファイルで提供されるすべてのパラメーターを使用して、sqlplus経由でパラメーター化されたOracleを発行したいと思います。これを行う方法はありますか?クエリには、ユーザーにプロンプトが表示されるのに妥当な数よりも多くのパラメーターがあり、このパラメーターを入力するときのユーザーエラーを排除したいと考えています。
パラメータ化されたクエリを発行する必要がある理由は、単純なSQLステートメントと、アプリケーションでパラメータ化されたクエリとして発行された同じクエリのパフォーマンスに大きな違いがあるためです。チェーンからアプリケーションコードを削除し、Oracleツールのみで違いを明らかにしたいと思います。
SQLを1つのファイルに、パラメーターを別のファイルにしたい場合、これはオプションです。 query.sql
に位置変数を割り当てて変数をバインドし、クエリを実行します。
variable p_owner varchar2(30);
variable p_column varchar2(30);
set verify off
set feedback off
begin
:p_owner := '&1';
:P_column := '&2';
end;
/
set feedback on
select table_name
from all_tab_columns
where owner = :p_owner
and column_name = :p_column;
exit 0;
そして、パラメータ値をテキストファイルに入れます。たとえば、parms.txt
:
SYS
OSUSER
そしてそれを一緒に入れます:
sqlplus -s user/password @query `cat parms.txt`
(これは明らかにUnixの場合です。同等のコマンドラインがWindowsの場合は、手元ではわかりません)。 parms.txt
を変更するか、別のファイルを使用すると、毎回同じハード解析されたプランが引き続き得られます。
パフォーマンスの問題は、バインド変数のピーク、特に「悪い計画で立ち往生」の説明に関連している可能性があるようです。実行プランは、最初のクエリの実行によって決定され、これらのパラメーターに適切なインデックスなどが選択される場合があります。その後の実行では、異なるパラメーターが新しいパラメーターに適している場合でも、同じプランを使用します。スタンドアロンのストレートSQLには個別の解析があり、したがって異なる(より適切な)プランになる可能性があります。過去には、ヒストグラムを使用しないように統計を手動で収集する必要がありました。
さて、パラメーター化されたクエリは、より良い結果をもたらします。これに似た方法を使用する方法は、UTLFILEを使用してパラメーターを開いて読み取る無名PL/SQLブロックを使用し、パラメーターをブロック内のクエリにフィードして、出力をファイルシステムに書き戻すことでした。
もちろんYMMV。
SQL Plusについて言及しているので、コマンドラインでこれを行っていると思いますか?もしそうなら、これはあなたのために働くかもしれません:
parms.shl:
export parm1=1
export parm2=15
export parm3=150
dojob.shl:
#!/bin/sh
# source our variables into our context.
. parms.shl
# call sqlplus and have the variables embedded.
sqlplus -s <<EOF
-- we're now in SQLPLUS
SELECT '$parm1', '$parm2', '$parm3'
FROM DUAL;
-- and exit out
EXIT;
EOF
次に、コマンドプロンプトで次のコマンドを実行します。
./dojob.shl
そして、結果は入力パラメータと一致するはずです。問題は、SQLがシェルスクリプト内にある必要があることです。 (sqlplusの@ filename.sql機能を使用しても、OSレベルの環境変数は表示されません。)
最もエレガントではありませんが、UTF_FILEオーバーヘッド/リスクなしで機能します。ほとんどの* NIX/BSDバリアントで動作するはずですが、Windowsバッチファイルに変換するのは難しくありません。
補足:データを保存する準備ができている場所にパラメータを保存してみませんか?つまり、データベースですか?パラメータを変更可能にする必要がある場合は、エンドユーザーがパラメータを更新できる画面または他のプロセスを記述し、プロセス内のテーブルにリンクするだけです。
サイドサイド注:この例では、変数のバインドに関して何もしていません。したがって、実行時間の長いステートメントで使用すると、パフォーマンスはそれほど向上しません。 sqlplusの変数を使用して、影響を軽減することができます(VARIABLEを介して変数をOS変数に設定してから、実際のコードでsqlplusの変数を再利用します。その後、Oracleはステートメントを適切に最適化できるはずです。 http:/ /www.adp-gmbh.ch/ora/sqlplus/use_vars.html )
名前付きパラメーターowner
およびtable
をファイルparams.sql
に定義します。
define owner=scott
define table=emp
定義ファイルを呼び出し、ファイルquery.sql
のパラメーターを使用します
@params.sql
select count(*) from &owner..&table
/
exit
..
の後の&owner
(2つのドット)は意図されています。
params.sql
とquery.sql
があるディレクトリに移動して、
sqlplus user/password@database @query.sql
名前付きパラメーターは、SQLのコマンドラインパラメーターと同じ方法でファイルquery.sql
で使用できますプラス。ファイルparams.sql
には、define
以外のステートメントを含めることができます。 SQL * plusマニュアルで説明されているSQL Plusで使用できる多くのテクニックです。