小さい頃はエラ呼吸

いつのまにやら肺で呼吸をしています。


【Oracle】直近5分以内に実行したSQLの履歴とバインド変数を確認する

はじめに

アプリケーションから発行したSQLがうまく動作しない場合、発行したSQLが分かれば調査の手がかりとなります。Oracleのv$sqlを参照すると、実行したSQLの履歴とバインド変数を確認することができます。

ざっくり言うと
  • SQLの実行履歴はv$sqlテーブルを見ると分かる。
  • 行が多すぎるため、SQLの断片を検索条件に含めると良い。
  • バインド変数の確認はv$sql_bind_captureを見ると分かる。

新・門外不出のOracle現場ワザ エキスパートが明かす運用・管理の極意 (DB Selection)
小田 圭二 大塚 信男 五十嵐 建平 谷 敦雄 宮崎 博之 神田 達成 村方 仁
翔泳社
売り上げランキング: 76,494

直近5分間に実行されたSQLを参照する

以下のクエリで直近5分間に実行されたSQLのIDとSQL文の最初の1000文字を取得できます。
sysユーザでログインします。

conn SYS/pwd AS sysdba

5分以内に実行されたSQLを参照する

SELECT SQL_ID,FIRST_LOAD_TIME,SQL_TEXT
FROM V$SQL
WHERE FIRST_LOAD_TIME BETWEEN TO_CHAR(SYSDATE - (5 / 24 / 60), 'YYYY-MM-DD/HH24:MI:SS') AND TO_CHAR(SYSDATE, 'YYYY-MM-DD/HH24:MI:SS')
ORDER BY FIRST_LOAD_TIME DESC;

実行した結果が以下です。なにやらたくさんSQLが出力されてよく分かりません。
f:id:replication:20150606133449p:plain
こんなときは、対象のテーブルを絞ります。たとえば、TABLE01に対するクエリだけを抽出する場合は、where句に条件を追加します。

SELECT SQL_ID,FIRST_LOAD_TIME,SQL_TEXT
FROM V$SQL
WHERE FIRST_LOAD_TIME BETWEEN TO_CHAR(SYSDATE - (5 / 24 / 60), 'YYYY-MM-DD/HH24:MI:SS') AND TO_CHAR(SYSDATE, 'YYYY-MM-DD/HH24:MI:SS')
AND SQL_TEXT LIKE UPPER('%TABLE01%')
ORDER BY FIRST_LOAD_TIME DESC;

f:id:replication:20150606133557p:plain
すると、今発行したSQLが抽出されます。

バインド変数を確認する

アプリケーションではwhere句の条件をバインド変数として定義して、アプリケーションから任意の値を渡して実行するケースがあります。
続いて、実行されたSQLのバインド変数を確認してみます。

1.はじめに共有プールをクリアします。

ALTER SYSTEM FLUSH SHARED_POOL;

2.バインド変数が使われているサンプルスクリプトを実行します。

variable vNum NUMBER;

declare
  vCnt NUMBER;
begin
  :vNum := '&id';
  select count(*) into vCnt from TABLE01 WHERE ID = :vNum;
end;
/[f:id:replication:20150606133809p:plain]

3.先ほどのクエリでv$sqlを参照します。
f:id:replication:20150606133809p:plain
SQLIDが"051cdac56gjcs"であることが分かります。
4.バインド変数を参照する。
バインド変数を参照するには、v$sql_bind_captureを参照します。

SELECT name,value_STRING FROM v$sql_bind_capture WHERE sql_id='051cdac56gjcs';

where句に渡されたバインド変数の値を取得できました。
f:id:replication:20150606133848p:plain