Oracle獲取繫結變數的各種方法

lhrbest發表於2017-09-05




Oracle解析和執行含有繫結變數的目標SQL時,如果滿足如下兩個條件之一,那麼該SQL中的繫結變數的具體輸入值就會被Oracle捕獲:

當含有繫結變數的目標SQL以硬解析的方式被執行時。

當含有繫結變數的目標SQL以軟解析或軟軟解析的方式重複執行時,Oracle在預設情況下至少得間隔15分鐘才會捕獲一次。這個15分鐘受隱含引數“_CURSOR_BIND_CAPTURE_INTERVAL”控制,預設值為900秒,即15分鐘。

SYS@orclasm > SET PAGESIZE 9999

SYS@orclasm > SET LINE 9999

SYS@orclasm > COL NAME FORMAT A40

SYS@orclasm > COL KSPPDESC FORMAT A60

SYS@orclasm > COL KSPPSTVL FORMAT A20

SYS@orclasm > SELECT A.INDX,

  2         A.KSPPINM NAME,

  3         A.KSPPDESC,

  4         B.KSPPSTVL

  5  FROM   X$KSPPI  A,

  6         X$KSPPCV B

  7  WHERE  A.INDX = B.INDX

  8  AND LOWER(A.KSPPINM) LIKE  LOWER('%&PARAMETER%');

Enter value for parameter: _CURSOR_BIND_CAPTURE_INTERVAL

old   8: AND LOWER(A.KSPPINM) LIKE  LOWER('%&PARAMETER%')

new   8: AND LOWER(A.KSPPINM) LIKE  LOWER('%_CURSOR_BIND_CAPTURE_INTERVAL%')

 

      INDX NAME                                     KSPPDESC                                                     KSPPSTVL

---------- ---------------------------------------- ------------------------------------------------------------ --------------------

      2140 _cursor_bind_capture_interval            interval (in seconds) between two bind capture for a cursor  900

需要注意的是,Oracle只會捕獲那些位於目標SQLWHERE條件中的繫結變數的具體輸入值,而對於那些使用了繫結變數的INSERT語句,不管該INSERT語句是否是以硬解析的方式執行,Oracle始終不會捕獲INSERT語句的VALUES子句中對應繫結變數的具體輸入值。

查詢檢視V$SQL_BIND_CAPTURE可以得到已執行目標SQL中繫結變數的具體輸入值。如果V$SQL_BIND_CAPTURE中查不到,那麼有可能對應的Shared Cursor已經從Shared Pool中被清除了,這時候可以嘗試從AWR相關的資料字典表DBA_HIST_SQLSTATDBA_HIST_SQLBIND中查詢。

查詢SQL語句如下所示:

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 = '01g03pruhphqc'

 ORDER BY D.CHILD_NUMBER, D.POSITION;

 

SELECT D.SQL_ID,

        D.NAME,

        D.POSITION,

        D.DATATYPE,

        D.DATATYPE_STRING,

        D.MAX_LENGTH,

        D.WAS_CAPTURED,

        D.LAST_CAPTURED,

        D.VALUE_STRING

  FROM DBA_HIST_SQLBIND D;

 

SELECT 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 = '01g03pruhphqc';

 

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;

 

SELECT 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';

 

SELECT * FROM DBA_HIST_SQLBIND  D WHERE D.SQL_ID = 'aug0d49nzbgtq';

測試示例如下所示:

CREATE TABLE T_BG_20170610_LHR(N NUMBER(10),V VARCHAR2(3000));

--SQL_TEXT1: 硬解析

DECLARE

  N NUMBER(10) :=1;   --分配22位元組的記憶體空間

  V VARCHAR2(32) :='XIAOMAIMIAO1';   --分配32位元組的記憶體空間

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V;

  COMMIT;

END;

/

--SQL_TEXT2: 硬解析

DECLARE

  N NUMBER(10) :=2;  --分配22位元組的記憶體空間

  V VARCHAR2(33) :='XIAOMAIMIAO2'; --分配128位元組的記憶體空間

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V;

  COMMIT;

END;

/

 

--SQL_TEXT3:  硬解析

DECLARE

  N NUMBER(10) :=3;  --分配22位元組的記憶體空間

  V VARCHAR2(129) :='XIAOMAIMIAO3'; --分配2000位元組的記憶體空間

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V;

  COMMIT;

END;

/

 

--SQL_TEXT4: 軟解析

DECLARE

  N NUMBER(10) :=4;  --分配22位元組的記憶體空間

  V VARCHAR2(2001) :='XIAOMAIMIAO4';  --分配2000位元組的記憶體空間

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V;

  COMMIT;

END;

/

--SQL_TEXT5: 軟解析

DECLARE

  N NUMBER(10) :=5;  --分配22位元組的記憶體空間

  V VARCHAR2(32767) :='XIAOMAIMIAO5';  --分配2000位元組的記憶體空間

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V;

  COMMIT;

END;

/

 

--SQL_TEXT6: 硬解析

DECLARE

  N NUMBER(10) :=6;  --分配22位元組的記憶體空間

  V VARCHAR2(32767) :=RPAD('XIAOMAIMIAO6',2002,'8');  --字串長度為2002,分配4000位元組的記憶體空間

BEGIN

  EXECUTE IMMEDIATE 'INSERT INTO T_BG_20170610_LHR SELECT * FROM T_BG_20170610_LHR WHERE N=:N AND V=:V ' USING N, V;

  COMMIT;

END;

/

查詢繫結變數的輸入值:

LHR@orclasm > COL NAME FORMAT A6

LHR@orclasm > COL VALUE_STRING FORMAT A15

LHR@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;

 

SQL_ID        CHILD_NUMBER CHILD_ADDRESS    NAME     POSITION   DATATYPE DATATYPE_STRING                MAX_LENGTH WAS LAST_CAPTURED       VALUE_STRING

------------- ------------ ---------------- ------ ---------- ---------- ------------------------------ ---------- --- ------------------- ---------------

aug0d49nzbgtq            0 0000000095C56BB0 :N              1          2 NUMBER                                 22 YES 2017-06-10 11:48:47 1

aug0d49nzbgtq            0 0000000095C56BB0 :V              2          1 VARCHAR2(32)                           32 YES 2017-06-10 11:48:47 XIAOMAIMIAO1

aug0d49nzbgtq            1 0000000095C5ECF0 :N              1          2 NUMBER                                 22 YES 2017-06-10 11:48:47 2

aug0d49nzbgtq            1 0000000095C5ECF0 :V              2          1 VARCHAR2(128)                         128 YES 2017-06-10 11:48:47 XIAOMAIMIAO2

aug0d49nzbgtq            2 0000000095C66750 :N              1          2 NUMBER                                 22 YES 2017-06-10 11:48:47 3

aug0d49nzbgtq            2 0000000095C66750 :V              2          1 VARCHAR2(2000)                       2000 YES 2017-06-10 11:48:47 XIAOMAIMIAO3

aug0d49nzbgtq            3 0000000095C22880 :N              1          2 NUMBER                                 22 YES 2017-06-10 11:48:48 6

aug0d49nzbgtq            3 0000000095C22880 :V              2          1 VARCHAR2(4000)                       4000 NO







1、查詢v$sql檢視
        sql_id, sql_text, bind_data,HASH_VALUE from v$sql   where sql_text Like '%select * from test where id1%';
它的記錄頻率受_cursor_bind_capture_interval 隱含引數控制,預設值900,表示每900秒記錄一次繫結值,可以透過alter system set "_cursor_bind_capture_interval"=10;

此時查詢到的data值得形式是這樣的:BEDA0B2002004F8482D10065FFFF0F00000000000000000000C0021602C102C0021602C102F0018003691532303132303431313032504F443834363135313635F0018003691532303132303431313032504F443834363135313730F0018003691532303132303431313032504F443834363135313731F0018003691532303132303431313032504F443834363135313734F0018003691532303132303431313032504F443834363135313735F0018003691532303132303431313032504F443834363135313739F0018003691532303132303431313032504F443834363135313830F0018003691532303132303431313032504F443834363135313833F0018003691532303132303431313032504F443834363135313834F0018003691532303132303431313032504F443834363135313838F0018003691532303132303431313032504F443834363135313839F0018003691532303132303431313032504F443834363135313933F0018003691532303132303431313032504F443834363135313934F0018003691532303132303431313032504F443834363135313937F0018003691532303132303431313032504F443834363135313938F0018003691532303132303431313032504F443834363135323033F0018003691532303132303431313032504F443834363135323034F0018003691532303132303431313032504F443834363135323037
這樣肯定是沒法看懂的

需喲進行轉換
select dbms_sqltune.extract_binds(bind_data) bind from v$sql WHERE SQL_TEXT LIKE '%FROM TEST11%';


2、查詢 SELECT VALUE_STRING FROM V$SQL_BIND_CAPTURE WHERE SQL_ID='abhf6n1xqgrr0';
透過v$sql_bind_capture檢視,可以檢視繫結變數,但是這個檢視不太給力,只能捕獲最後一次記錄的繫結變數值。

而且兩次捕獲的間隔有一個隱含引數控制。預設是900秒,才會重新開始捕獲。在900內,繫結變數值的改變不會反應在這個檢視中。

10G以後可以透過如下方法檢視AWR報告裡記錄的SQL的繫結變數值。

 

select snap_id, name, position, value_string,last_captured,WAS_CAPTURED  from dba_hist_sqlbind  where sql_id = '576c1s91gua19' and snap_id='20433';

----------SNAP_ID就是AWR報告的快照ID

----------name,繫結變數的名稱

----------position,繫結值在SQL語句中的位置,以123進行標註  

---------value_string,就是繫結變數值

---------,last_captured,最後捕獲到的時間

---------WAS_CAPTURED,是否繫結被捕獲,where子句前面的繫結不進行捕獲。

dba_hist_sqlbind檢視強大的地方在於,它記錄了每個AWR報告裡的SQL的繫結變數值,當然這個繫結變數值也是AWR生成的時候從v$sql_bind_capture取樣獲得的。

透過這個檢視,我們能夠獲得比較多的繫結變數值,對於我們排查問題,這些值一般足夠了。

還有一個需要注意的地方是,這兩個檢視中記錄的繫結變數只對where條件後面的繫結進行捕獲,這點需要使用的時候注意。

3、查詢 dba_hist_sqlbind VALUE_STRING列
DBA_HIST_SQLBIND是檢視V$SQL_BIND_CAPTURE歷史快照

4、查詢wrh$_sqlstat
     select dbms_sqltune.extract_bind(bind_data, 1).value_string
     from wrh$_sqlstat
      where sql_id = '88dz0k2qvg876'----根據繫結變數的多少增加dbms_sqltune.extract_bind(bind_data, 2).value_string等




ORACLE獲取SQL繫結變數值的方法總結

 

本文總結一下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

 

clip_image001

 

 

 

如果此時你給變數NAME賦值為kerry,然後你使用上面SQL語句查詢,你會發現繫結變數的值依然為"KKKK",這個是因為繫結變數何時被捕獲是有一定規律的:

 

含有繫結變數的sql語句被硬解析時

 

當含有繫結變數的sql語句以軟解析或者軟軟解析方式重複執行時,該SQL語句中的繫結變數的具體輸入值也可能被ORACLE捕獲,只不過預設情況下這種捕獲操作

受隱含引數_cursor_bind_capture_interval影響,預設需要間隔15900秒)分鐘才會做一次

 

 

SQL> exec :NAME :='kerry';

 

PL/SQL procedure successfully completed.

 

SQL> /

 

        ID NAME

---------- --------------------------------

      1000 kerry

 

SQL>

 

 

 

 

方法2:查詢wrh$_sqlstat

 

 

V$SQL中有BIND_DATA欄位,當SQL被解析時,就會放到BIND_DATA欄位中,最終會被存入wrh$_sqlstat。關於wrh$_sqlstat的介紹如下所示:

 

wrh$_sqlstat contains a history for SQL execution statistics and stores snapshots of v$sql view.

 

 

wrh$_sqlstat中儲存是v$sql的執行統計資訊的快照的歷史記錄,那麼從這裡可以查詢到一些歷史繫結變數的值,但是也有可能v$sql的快照資訊沒有被捕獲到(如滿足什麼條件才會被捕獲呢?)。如下截圖所示

 

 

 

 

SQL> select dbms_sqltune.extract_bind(bind_data, 1).value_string
  2  from wrh$_sqlstat
  3  where sql_id='0r7m5jyz9ng09';
 
no rows selected

 

clip_image002

 

 

 

 

如上測試所示,這個獲取繫結變數值的方法有一定的缺陷性,有可能V$SQL快照資訊沒有被捕獲到,導致wrh$_sqlstat

裡面查不到對應的資訊。

 

 

 

注意,如果有1個的繫結值,可以使用如下查詢

 

 

select dbms_sqltune.extract_bind(bind_data, 1).value_string   
 
from wrh$_sqlstat
 
where sql_id = '1t2r2p48w4p0g'

 

 

 

如果有2個繫結值,可以使用如下查詢

 

 

select dbms_sqltune.extract_bind(bind_data, 1).value_string||
'
'--'||dbms_sqltune.extract_bind(bind_data, 2).value_string
 
  from wrh$_sqlstat
 
 where sql_id = '1t2r2p48w4p0g'

 

 

如果有多個繫結變數,使用類似下面SQL

 

select dbms_sqltune.extract_bind(bind_data, 1).value_string
     ||'-'|| dbms_sqltune.extract_bind(bind_data, 2).value_string 
     ||'-'|| dbms_sqltune.extract_bind(bind_data, 3).value_string 
     ||'-'|| dbms_sqltune.extract_bind(bind_data, 4).value_string 
     ||'-'|| dbms_sqltune.extract_bind(bind_data, 5).value_string 
     ||'-'|| dbms_sqltune.extract_bind(bind_data, 6).value_string
from wrh$_sqlstat
where sql_id = '1t2r2p48w4p0g'
/

 

 

 

 

 

方法3v$sql_bind_capture

 

 

使用 V$SQL_BIND_CAPTURE獲取繫結變數的值,也有一些限制:

 

1、如果STATISTICS_LEVEL設定成BASIC,那繫結變數的捕捉就會關閉(Bind capture is disabled when the STATISTICS_LEVEL initialization parameter is set to BASIC.

2、預設是900秒捕捉一次繫結變數值,由_cursor_bind_capture_interval引數控制。

3V$SQL_BIND_CAPTURE檢視中記錄的繫結變數只對WHERE條件後面的繫結進行捕獲,這點需要使用的時候注意。

    對於DML操作,V$SQL_BIND_CAPTURE無法獲取繫結變數的值。

 

 

SQL> COL NAME FOR A12;
SQL> COL DATATYPE_STRING FOR A24;
SQL> COL VALUE_STRING FOR A32;
SQL> SELECT NAME, 
  2         DATATYPE_STRING, 
  3         VALUE_STRING, 
  4         MAX_LENGTH, 
  5         LAST_CAPTURED 
  6  FROM   V$SQL_BIND_CAPTURE 
  7  WHERE  SQL_ID = '1t2r2p48W4P0g'; 
 
NAME         DATATYPE_STRING          VALUE_STRING                     MAX_LENGTH LAST_CAPT
------------ ------------------------ -------------------------------- ---------- ---------
:NAME        NVARCHAR2(128)           KD                                    128 04-SEP-17
 
SQL> 

 

 

v$sql_bind_capture檢視,可以檢視繫結變數,但是這個檢視不太給力,只能捕獲最後一次記錄的繫結變數值。而且兩次捕獲的間隔也是受隱含引數_cursor_bind_capture_interval控制。預設是900秒後才會重新開始捕獲。在900內,繫結變數值的改變不會反應在這個檢視中。這個跟v$sql獲取變數值是一樣的。

 

 

SQL> EXEC :NAME :='kerry';

 

PL/SQL procedure successfully completed.

 

SQL>/

 

        ID NAME

---------- --------------------------------

      1000 kerry

 

SQL>

 

 

如上所示,我給變數賦予新的值,然後重新執行一次,你執行上面SQL,發現繫結變數的值為kerry了,之前的值KD就無法找到了。所以這個也是這個檢視的一個侷限性。(注意,實驗結果結果也有可能是KD,這個取決於實驗的時間間隔與隱含引數_cursor_bind_capture_interval的值有關係)

 

 

clip_image003

 

 

This view can be joined with V$SQLAREA on (HASH_VALUE, ADDRESS) and with V$SQL on (HASH_VALUE, CHILD_ADDRESS).

 

 

 

--
SET PAUSE ON
SET PAUSE 'Press Return to Continue'
SET PAGESIZE 60
SET LINESIZE 300
 
COLUMN sql_text FORMAT A120
COLUMN sql_id FORMAT A13
COLUMN bind_name FORMAT A10
COLUMN bind_value FORMAT A26
 
SELECT
  sql_id,
  t.sql_text sql_text,  
  b.name bind_name,
  b.value_string bind_value
FROM
  v$sql t
JOIN
  v$sql_bind_capture b  using (sql_id)
WHERE
  b.value_string is not null
AND
  sql_id='&sqlid'
/
 
 
SELECT
  b.sql_id,
  t.sql_text sql_text,  
  b.name bind_name,
  b.value_string bind_value
FROM
  v$sql t
JOIN
  v$sql_bind_capture b  on t.hash_value = b.hash_value and t.child_address = b.child_address
WHERE
  b.value_string is not null
AND
  b.sql_id='&sqlid'
/

 

 

 

方法4:查詢檢視DBA_HIST_SQLBIND.

 

 

DBA_HIST_SQLBIND是檢視V$SQL_BIND_CAPTURE歷史快照所以從檢視DBA_HIST_SQLBIND能查到多個繫結變數的值。但是這裡依然會遇到一個問題,就是有可能歷史快照沒有被捕獲到DBA_HIST_SQLBIND下。如下測試所示:

 

 

 

SELECT SNAP_ID, 
       NAME, 
       POSITION, 
       VALUE_STRING, 
       LAST_CAPTURED, 
       WAS_CAPTURED 
FROM   DBA_HIST_SQLBIND 
WHERE  SQL_ID = '&SQL_ID' 
       AND SNAP_ID = &SNAP_ID; 
 
 
 
 
SELECT SNAP_ID, 
       NAME, 
       POSITION, 
       VALUE_STRING, 
       LAST_CAPTURED, 
       WAS_CAPTURED 
FROM   DBA_HIST_SQLBIND 
WHERE  SQL_ID = '&SQL_ID';

 

 

 

SQL> SELECT SNAP_ID, 
  2         NAME, 
  3         POSITION, 
  4         VALUE_STRING, 
  5         LAST_CAPTURED, 
  6         WAS_CAPTURED 
  7  FROM   DBA_HIST_SQLBIND 
  8  WHERE  SQL_ID = '&SQL_ID';
Enter value for sql_id: 1t2r2p48w4p0g
old   8: WHERE  SQL_ID = '&SQL_ID'
new   8: WHERE  SQL_ID = '1t2r2p48w4p0g'
 
no rows selected
 
SQL> exec dbms_workload_repository.create_snapshot();
 
PL/SQL procedure successfully completed.
 
SQL> SELECT SNAP_ID, 
  2         NAME, 
  3         POSITION, 
  4         VALUE_STRING, 
  5         LAST_CAPTURED, 
  6         WAS_CAPTURED 
FROM   DBA_HIST_SQLBIND 
  7    8  WHERE  SQL_ID = '&SQL_ID';
Enter value for sql_id: 1t2r2p48w4p0g
old   8: WHERE  SQL_ID = '&SQL_ID'
new   8: WHERE  SQL_ID = '1t2r2p48w4p0g'
 
no rows selected
 
SQL> 

 

 

clip_image004

 

 

 

 

方法5dbms_xplan.display_cursor

 

 

 sql_id       指定位於庫快取執行計劃中SQL語句的父遊標。預設值為null。當使用預設值時當前會話的最後一條

                SQL語句的執行計劃將被返回。 可以透過查詢V$SQL V$SQLAREASQL_ID列來獲得SQL語句的SQL_ID

 

child_number  指定父遊標下子游標的序號。即指定被返回執行計劃的SQL語句的子游標。預設值為0。如果為null

               則sql_id所指父遊標下所有子游標的執行計劃都將被返回。

      

  format       控制SQL語句執行計劃的輸出部分,即哪些可以顯示哪些不顯示。

 

 

select * from table(dbms_xplan.display_cursor('1t2r2p48w4p0g', 0, 'ADVANCED'));
 
 
-------------------------------------
SELECT * FROM TEST WHERE NAME=:NAME
 
Plan hash value: 1357081020
 
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |       |       |     3 (100)|          |
|*  1 |  TABLE ACCESS FULL| TEST |     1 |    31 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------
 
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
 
   1 - SEL$1 / TEST@SEL$1
 
Outline Data
-------------
 
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.1')
      DB_VERSION('11.2.0.1')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      FULL(@"SEL$1" "TEST"@"SEL$1")
      END_OUTLINE_DATA
  */
 
Peeked Binds (identified by position):
--------------------------------------
 
   1 - :NAME (VARCHAR2(30), CSID=873): 'KKK'
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter("NAME"=:NAME)
 
Column Projection Information (identified by operation id):
-----------------------------------------------------------
 
   1 - "TEST"."ID"[NUMBER,22], "NAME"[VARCHAR2,32]

 

 

方法610046事件捕獲繫結變數

 

 

alter session set events '10046 trace name context forever, level 4'; --level=4 表示啟用SQL_TRACE並捕捉跟蹤檔案中的繫結變數。

 

實驗在此略過,其實ORACLE中seq$表更新頻繁的分析案例中已經展示如何使用10046事件捕獲繫結變數的值。另外v$sql,v$sql_bind_capturedba_hist_sqlbind只能捕獲查詢SQL(確切的說,只對WHERE條件後面的繫結變數進行捕獲)的繫結變數,但10046也能捕獲DMLSQL的值

 

 

最後如果需要可以透過alter system set "_cursor_bind_capture_interval"=10; 修改繫結變數捕獲的時間間隔。

作者:瀟湘隱者


 

 




About Me

.............................................................................................................................................

● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除

● 本文在itpub(http://blog.itpub.net/26736162/abstract/1/)、部落格園(http://www.cnblogs.com/lhrbest)和個人微信公眾號(xiaomaimiaolhr)上有同步更新

● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/

● 本文部落格園地址:http://www.cnblogs.com/lhrbest

● 本文pdf版、個人簡介及小麥苗雲盤地址:http://blog.itpub.net/26736162/viewspace-1624453/

● 資料庫筆試面試題庫及解答:http://blog.itpub.net/26736162/viewspace-2134706/

● DBA寶典今日頭條號地址:

.............................................................................................................................................

● QQ群號:230161599(滿)、618766405

● 微信群:可加我微信,我拉大家進群,非誠勿擾

● 聯絡我請加QQ好友646634621,註明新增緣由

● 於 2017-09-01 09:00 ~ 2017-09-30 22:00 在魔都完成

● 文章內容來源於小麥苗的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解

● 版權所有,歡迎分享本文,轉載請保留出處

.............................................................................................................................................

小麥苗的微店

小麥苗出版的資料庫類叢書http://blog.itpub.net/26736162/viewspace-2142121/

.............................................................................................................................................

使用微信客戶端掃描下面的二維碼來關注小麥苗的微信公眾號(xiaomaimiaolhr)及QQ群(DBA寶典),學習最實用的資料庫技術。

   小麥苗的微信公眾號      小麥苗的DBA寶典QQ群1     小麥苗的DBA寶典QQ群2        小麥苗的微店

.............................................................................................................................................

Oracle獲取繫結變數的各種方法
DBA筆試面試講解群1
DBA筆試面試講解群2
歡迎與我聯絡



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2144519/,如需轉載,請註明出處,否則將追究法律責任。

相關文章