本文總結一下ORACLE資料庫中如何獲取SQL綁定變數值的方法,在SQL優化調優過程中,經常會用到這方面的知識點。在此梳理、總結一下,方面日後查找、翻閱。 方法1:查詢V$SQL V$SQL視圖中的BIND_DATA欄位用來存儲綁定變數的值,但是從這個視圖查詢綁定變數的值,有很大的局限性: 1: 它... ...
本文總結一下ORACLE資料庫中如何獲取SQL綁定變數值的方法,在SQL優化調優過程中,經常會用到這方面的知識點。在此梳理、總結一下,方面日後查找、翻閱。
方法1:查詢V$SQL
V$SQL視圖中的BIND_DATA欄位用來存儲綁定變數的值,但是從這個視圖查詢綁定變數的值,有很大的局限性:
1: 它的記錄頻率受_cursor_bind_capture_interval隱含參數控制,預設值為900,表示每900秒記錄一次綁定值,也就是說在900內,綁定變數值的改變不會反應在這個視圖中。除非你調整隱含參數_cursor_bind_capture_interval
2: 它記錄的僅僅最後一次捕獲的綁定變數值。
3: BIND_DATA數據類型為RAW,需要進行轉換。
可以使用下麵兩種方式來查看綁定變數的值。
COL SQL_ID FOR A14;
COL SQL_TEXT FOR A32;
COL HASH_VALUE FOR 99999999999;
COL BIND_DATA FOR A32;
SELECT SQL_ID
,SQL_TEXT
,LITERAL_HASH_VALUE
,HASH_VALUE
,DBMS_SQLTUNE.EXTRACT_BINDS(BIND_DATA) BIND_DATA
FROM V$SQL
WHERE SQL_TEXT LIKE ''SELECT * FROM TEST%';
COL SQL_ID FOR A14;
COL SQL_TEXT FOR A32;
COL HASH_VALUE FOR 99999999999;
COL BIND_DATA FOR A32;
SELECT SQL_ID
,SQL_TEXT
,LITERAL_HASH_VALUE
,HASH_VALUE
,DBMS_SQLTUNE.EXTRACT_BIND(BIND_DATA,1).VALUE_STRING BIND_DATA
FROM V$SQL
WHERE SQL_TEXT LIKE 'SELECT * FROM TEST%';
如下實驗所示,我們在一個會話中使用綁定變數的查詢SQL語句,然後,我們來嘗試獲取綁定變數的值,如下所示:
SQL> SHOW USER;
USER is "TEST"
SQL> DESC TEST;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER(10)
NAME VARCHAR2(32)
SQL>
SQL> VARIABLE NAME NVARCHAR2(32);
SQL> EXEC :NAME :='KKKK';
PL/SQL procedure successfully completed.
SQL> SELECT * FROM TEST WHERE NAME=:NAME;
no rows selected
SQL>
SQL>SHOW USER;
USER is "SYS"
SQL> COL SQL_ID FOR A14;
SQL> COL SQL_TEXT FOR A32;
SQL> COL HASH_VALUE FOR 99999999999;
SQL> COL BIND_DATA FOR A32;
SQL> SELECT SQL_ID
2 ,SQL_TEXT
3 ,LITERAL_HASH_VALUE
4 ,HASH_VALUE
5 ,DBMS_SQLTUNE.EXTRACT_BINDS(BIND_DATA) BIND_DATA
6 FROM V$SQL
7 WHERE SQL_TEXT LIKE 'SELECT * FROM TEST%';
SQL_ID SQL_TEXT LITERAL_HASH_VALUE HASH_VALUE BIND_DATA(NAME, POSITION, DUP_PO
-------------- -------------------------------- ------------------ ------------ --------------------------------
0r7m5jyz9ng09 SELECT * FROM TEST WHERE NAME=:N 0 3197778953 SQL_BIND_SET(SQL_BIND(NULL, 1, N
AME ULL, 1, 'NVARCHAR2(128)', 2000,
NULL, NULL, 128, '04-SEP-17', 'K
KKK', ANYDATA()))
SQL> COL SQL_ID FOR A14;
SQL> COL SQL_TEXT FOR A32;
SQL> COL HASH_VALUE FOR 99999999999;
SQL> COL BIND_DATA FOR A32;
SQL> SELECT SQL_ID
2 ,SQL_TEXT
3 ,LITERAL_HASH_VALUE
4 ,HASH_VALUE
5 ,DBMS_SQLTUNE.EXTRACT_BIND(BIND_DATA,1).VALUE_STRING BIND_DATA
6 FROM V$SQL
7 WHERE SQL_TEXT LIKE 'SELECT * FROM TEST%';
SQL_ID SQL_TEXT LITERAL_HASH_VALUE HASH_VALUE BIND_DATA
-------------- -------------------------------- ------------------ ------------ --------------------------------
0r7m5jyz9ng09 SELECT * FROM TEST WHERE NAME=:N 0 3197778953 KKKK
如果此時你給變數NAME賦值為kerry,然後你使用上面SQL語句查詢,你會發現綁定變數的值依然為"KKKK",這個是因為綁定變數何時被捕獲是有一定規律的:
1 含有綁定變數的sql語句被硬解析時
2 當含有綁定變數的sql語句以軟解析或者軟軟解析方式重覆執行時,該SQL語句中的綁定變數的具體輸入值也可能被ORACLE捕獲,只不過預設情況下這種捕獲操作
受隱含參數_cursor_bind_capture_interval影響,預設需要間隔15(900秒)分鐘才會做一次