2

次のような SQL スクリプトがあります。

Variable nb number;
Variable var1   varchar2(30);
Variable var2   varchar2(30);
EXEC :var1 := '&1';
EXEC :var2 := '&2';

BEGIN
    SELECT count(*) into :nb FROM some_table where col1=:var1 and col2=:var2;
END;
/
print :nb;
exit :nb;

このスクリプトは、次のようなコマンドを使用して複数回実行されます。

sqlplus @myscript.sql LITERAL_A1 LITERAL_B1
sqlplus @myscript.sql LITERAL_A2 LITERAL_B2
sqlplus @myscript.sql LITERAL_A3 LITERAL_B3
sqlplus @myscript.sql LITERAL_A4 LITERAL_B4

私の質問は、共有プールへのアクセスに関連しています。

クエリを実行すると:

select executions,sql_text 
from v$sqlarea 
where ( sql_text like '%var1%' or  sql_text like '%var2%' ) 

次のような出力が得られます。

BEGIN SELECT count(*) into :nb1 FROM some_table where col1=:var1 and col2=:var2; END; [ Execution=4]
BEGIN :var1 := 'LITERAL_A1' ; END;[ Execution=1]
BEGIN :var2 := 'LITERAL_B1'; END; [ Execution=1]
BEGIN :var1 := 'LITERAL_A2' ; END;[ Execution=1]
BEGIN :var2 := 'LITERAL_B2'; END; [ Execution=1]
BEGIN :var1 := 'LITERAL_A3' ; END;[ Execution=1]
BEGIN :var2 := 'LITERAL_B3'; END; [ Execution=1]
BEGIN :var1 := 'LITERAL_A4' ; END;[ Execution=1]
BEGIN :var2 := 'LITERAL_B4'; END; [ Execution=1]

これは、メインの選択クエリでの競合が解消されたものの、バインド変数の初期化で競合が追加されたことを示しています。これを取り除く方法はありますか?

4

1 に答える 1

4

「バインド変数の初期化に競合が追加されました」

競合とは、ここでそれをどのように使用するかを意味するものではありません。競合やリソースの競合はありません。

むしろ、あなたが持っているのは、多くの同様のステートメントです。SQL*Plus には置換変数があるため、これらは類似しています。これらはバインド変数ではなく、ハードコードされた値に解決されます。したがって、各実行は異なるため、キャッシュ内のステートメントも異なります。

これはすべて完全に予期された動作です。本当に問題があると思うなら、それはおそらく間違っています。Oracle はこれらのワンショット ステートメントを期限切れにするため、より頻繁に使用されるクエリのキャッシュが妨げられることはほとんどありません。

本当にそれらをなくしたい場合は、SQL*Plus スクリプトの使用をやめ、代わりにストアド プロシージャに移行してください。

于 2014-11-26T08:17:39.713 に答える