在Oracle中,如何獲得已執行的目標SQL中的綁定變量的值?ide
當Oracle解析和執行含有綁定變量的目標SQL時,若是知足以下兩個條件之一,那麼該SQL中的綁定變量的具體輸入值就會被Oracle捕獲:測試
l 當含有綁定變量的目標SQL以硬解析的方式被執行時。spa
l 當含有綁定變量的目標SQL以軟解析或軟軟解析的方式重複執行時,Oracle在默認狀況下至少得間隔15分鐘纔會捕獲一次。這個15分鐘受隱含參數「_CURSOR_BIND_CAPTURE_INTERVAL」控制,默認值爲900秒,即15分鐘。blog
1SYS@orclasm > SET PAGESIZE 9999 2SYS@orclasm > SET LINE 9999 3SYS@orclasm > COL NAME FORMAT A40 4SYS@orclasm > COL KSPPDESC FORMAT A60 5SYS@orclasm > COL KSPPSTVL FORMAT A20 6SYS@orclasm > SELECT A.INDX, 7 2 A.KSPPINM NAME, 8 3 A.KSPPDESC, 9 4 B.KSPPSTVL 10 5 FROM X$KSPPI A, 11 6 X$KSPPCV B 12 7 WHERE A.INDX = B.INDX 13 8 AND LOWER(A.KSPPINM) LIKE LOWER('%&PARAMETER%'); 14Enter value for parameter: _CURSOR_BIND_CAPTURE_INTERVAL 15old 8: AND LOWER(A.KSPPINM) LIKE LOWER('%&PARAMETER%') 16new 8: AND LOWER(A.KSPPINM) LIKE LOWER('%_CURSOR_BIND_CAPTURE_INTERVAL%') 17 18 INDX NAME KSPPDESC KSPPSTVL 19---------- ---------------------------------------- ------------------------------------------------------------ -------------------- 20 2140 _cursor_bind_capture_interval interval (in seconds) between two bind capture for a cursor 900
須要注意的是,Oracle只會捕獲那些位於目標SQL的WHERE條件中的綁定變量的具體輸入值,而對於那些使用了綁定變量的INSERT語句,無論該INSERT語句是不是以硬解析的方式執行,Oracle始終不會捕獲INSERT語句的VALUES子句中對應綁定變量的具體輸入值。內存
查詢視圖V$SQL_BIND_CAPTURE或V$SQL能夠獲得已執行目標SQL中綁定變量的具體輸入值。若是V$SQL_BIND_CAPTURE中查不到,那麼有可能對應的Shared Cursor已經從Shared Pool中被清除了,這時候能夠嘗試從AWR相關的數據字典表DBA_HIST_SQLSTAT或DBA_HIST_SQLBIND中查詢。另外,也能夠經過DBMS_XPLAN.DISPLAY_CURSOR和10046來獲取綁定變量的值。字符串
查詢SQL語句以下所示:it
1COL SQL_ID FOR A14; 2COL SQL_TEXT FOR A32; 3COL HASH_VALUE FOR 99999999999; 4COL BIND_DATA FOR A32; 5SELECT SQL_ID 6 ,SQL_TEXT 7 ,LITERAL_HASH_VALUE 8 ,HASH_VALUE 9 ,DBMS_SQLTUNE.EXTRACT_BINDS(BIND_DATA) BIND_DATA 10FROM V$SQL 11WHERE SQL_TEXT LIKE ''SELECT * FROM TEST%'; 12 13 14COL SQL_ID FOR A14; 15COL SQL_TEXT FOR A32; 16COL HASH_VALUE FOR 99999999999; 17COL BIND_DATA FOR A32; 18SELECT SQL_ID 19 ,SQL_TEXT 20 ,LITERAL_HASH_VALUE 21 ,HASH_VALUE 22 ,DBMS_SQLTUNE.EXTRACT_BIND(BIND_DATA,1).VALUE_STRING BIND_DATA 23FROM V$SQL 24WHERE SQL_TEXT LIKE 'SELECT * FROM TEST%'; 25 26SELECT D.SQL_ID, 27 D.CHILD_NUMBER, 28 D.CHILD_ADDRESS, 29 D.NAME, 30 D.POSITION, 31 D.DATATYPE, 32 D.DATATYPE_STRING, 33 D.MAX_LENGTH, 34 D.WAS_CAPTURED, 35 D.LAST_CAPTURED, 36 D.VALUE_STRING 37 FROM V$SQL_BIND_CAPTURE D 38 WHERE D.SQL_ID = '01g03pruhphqc' 39 ORDER BY D.CHILD_NUMBER, D.POSITION; 40 41SELECT D.SQL_ID, 42 D.NAME, 43 D.POSITION, 44 D.DATATYPE, 45 D.DATATYPE_STRING, 46 D.MAX_LENGTH, 47 D.WAS_CAPTURED, 48 D.LAST_CAPTURED, 49 D.VALUE_STRING 50 FROM DBA_HIST_SQLBIND D; 51 52SELECT D.SNAP_ID, 53 DBMS_SQLTUNE.EXTRACT_BIND(D.BIND_DATA, 1).VALUE_STRING BIND1, 54 DBMS_SQLTUNE.EXTRACT_BIND(D.BIND_DATA, 1).VALUE_STRING BIND2 55 FROM DBA_HIST_SQLSTAT D 56 WHERE D.SQL_ID = '01g03pruhphqc'; 57 58SELECT D.SQL_ID,D.CHILD_NUMBER,D.CHILD_ADDRESS,D.NAME,D.POSITION,D.DATATYPE, D.DATATYPE_STRING,D.MAX_LENGTH,D.WAS_CAPTURED,D.LAST_CAPTURED,D.VALUE_STRING FROM V$SQL_BIND_CAPTURE D WHERE D.SQL_ID = 'aug0d49nzbgtq' ORDER BY D.CHILD_NUMBER,D.POSITION; 59 60SELECT D.SNAP_ID,DBMS_SQLTUNE.EXTRACT_BIND(D.BIND_DATA,1).VALUE_STRING BIND1,DBMS_SQLTUNE.EXTRACT_BIND(D.BIND_DATA,1).VALUE_STRING BIND2 FROM DBA_HIST_SQLSTAT D WHERE D.SQL_ID = 'aug0d49nzbgtq'; 61 62SELECT * FROM DBA_HIST_SQLBIND D WHERE D.SQL_ID = 'aug0d49nzbgtq'; 63 64SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('1t2r2p48w4p0g', 0, 'ADVANCED')); 65 66ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 4'; --LEVEL=4 表示啓用SQL_TRACE並捕捉跟蹤文件中的綁定變量。 67
測試示例以下所示:asm
1CREATE TABLE T_BG_20170610_LHR(N NUMBER(10),V VARCHAR2(3000)); 2--SQL_TEXT1: 硬解析 3DECLARE 4 N NUMBER(10) :=1; --分配22字節的內存空間 5 V VARCHAR2(32) :='XIAOMAIMIAO1'; --分配32字節的內存空間 6BEGIN 7 EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V; 8 COMMIT; 9END; 10/ 11--SQL_TEXT2: 硬解析 12DECLARE 13 N NUMBER(10) :=2; --分配22字節的內存空間 14 V VARCHAR2(33) :='XIAOMAIMIAO2'; --分配128字節的內存空間 15BEGIN 16 EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V; 17 COMMIT; 18END; 19/ 20 21--SQL_TEXT3: 硬解析 22DECLARE 23 N NUMBER(10) :=3; --分配22字節的內存空間 24 V VARCHAR2(129) :='XIAOMAIMIAO3'; --分配2000字節的內存空間 25BEGIN 26 EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V; 27 COMMIT; 28END; 29/ 30 31--SQL_TEXT4: 軟解析 32DECLARE 33 N NUMBER(10) :=4; --分配22字節的內存空間 34 V VARCHAR2(2001) :='XIAOMAIMIAO4'; --分配2000字節的內存空間 35BEGIN 36 EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V; 37 COMMIT; 38END; 39/ 40--SQL_TEXT5: 軟解析 41DECLARE 42 N NUMBER(10) :=5; --分配22字節的內存空間 43 V VARCHAR2(32767) :='XIAOMAIMIAO5'; --分配2000字節的內存空間 44BEGIN 45 EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V; 46 COMMIT; 47END; 48/ 49 50--SQL_TEXT6: 硬解析 51DECLARE 52 N NUMBER(10) :=6; --分配22字節的內存空間 53 V VARCHAR2(32767) :=RPAD('XIAOMAIMIAO6',2002,'8'); --字符串長度爲2002,分配4000字節的內存空間 54BEGIN 55 EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V; 56 COMMIT; 57END; 58/
查詢綁定變量的輸入值:class
1LHR@orclasm > COL NAME FORMAT A6 2LHR@orclasm > COL VALUE_STRING FORMAT A15 3LHR@orclasm > SELECT D.SQL_ID,D.CHILD_NUMBER,D.CHILD_ADDRESS,D.NAME,D.POSITION,D.DATATYPE, D.DATATYPE_STRING,D.MAX_LENGTH,D.WAS_CAPTURED,D.LAST_CAPTURED,D.VALUE_STRING FROM V$SQL_BIND_CAPTURE D WHERE D.SQL_ID = 'aug0d49nzbgtq' ORDER BY D.CHILD_NUMBER,D.POSITION; 4 5SQL_ID CHILD_NUMBER CHILD_ADDRESS NAME POSITION DATATYPE DATATYPE_STRING MAX_LENGTH WAS LAST_CAPTURED VALUE_STRING 6------------- ------------ ---------------- ------ ---------- ---------- ------------------------------ ---------- --- ------------------- --------------- 7aug0d49nzbgtq 0 0000000095C56BB0 :N 1 2 NUMBER 22 YES 2017-06-10 11:48:47 1 8aug0d49nzbgtq 0 0000000095C56BB0 :V 2 1 VARCHAR2(32) 32 YES 2017-06-10 11:48:47 XIAOMAIMIAO1 9aug0d49nzbgtq 1 0000000095C5ECF0 :N 1 2 NUMBER 22 YES 2017-06-10 11:48:47 2 10aug0d49nzbgtq 1 0000000095C5ECF0 :V 2 1 VARCHAR2(128) 128 YES 2017-06-10 11:48:47 XIAOMAIMIAO2 11aug0d49nzbgtq 2 0000000095C66750 :N 1 2 NUMBER 22 YES 2017-06-10 11:48:47 3 12aug0d49nzbgtq 2 0000000095C66750 :V 2 1 VARCHAR2(2000) 2000 YES 2017-06-10 11:48:47 XIAOMAIMIAO3 13aug0d49nzbgtq 3 0000000095C22880 :N 1 2 NUMBER 22 YES 2017-06-10 11:48:48 6 14aug0d49nzbgtq 3 0000000095C22880 :V 2 1 VARCHAR2(4000) 4000 NO