watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

        那么对于绑定来说,如何得到已执行的目标SQL中的绑定变量的值呢?


 当面对的是已经执行过且使用了绑定变量的目标SQL时,我们就必须想案发得到这些目标SQL中绑定变量的实际输入值。因为只有知道了绑定变量的实际输入值,我们才有可能在原数据库环境中重现目标SQL原先的执行计划,才能确认我们对其执行计划做的调整是有针对性的,是真实有效的。

        如何得到已执行目标SQL中的绑定变量的输入值?就是查询视图v$sql_bind_capture。如果v$sql_bind_capture中查不到,那么有可能对应的shared cursor已经被age out出shared pool了,这时候可以尝试去awr repository相关的数据字典表dba_hist_sqlstat或dba_hist_sqlbind中查询。

        当Oracle解析和执行含有绑定变量的目标SQL时,如果满足如下调价,则SQL中绑定变量的具体输入值就会被Oracle捕获,通过视图v$sql_bind_capture查询。

        a、当含有绑定变量的目标SQL以硬解析的方式被执行时。

        b、当含有绑定变量的目标SQL以软解析、软软解析方式重复执行时,该SQL中的绑定变量的具体输入值也可能被Oracle捕获,只不过默认情况下这种捕获操作Oracle至少间隔15分钟才会做一次。

需要注意的是:Oracle只会捕获那些位于目标SQL的where条件中的绑定变量的具体输入值,而对于那些使用了绑定变量的insert语句,不管该insert语句是否以硬解析的方式执行,Oracle始终不会捕获其values字句中对应绑定变量的具体输入值。

通过如下的测试来模拟如何得到绑定变量的值--根据前边绑定变量分级操作来造t表环境:


SQL> select n,length(v) from t;          N  LENGTH(V)---------- ----------         1          5         2          5         3          5         4          5         5          5         6       2002 已选择 6 行。

造t表,插入6条数据进入,如上所示:

SQL> col sql_text for a40

SQL> set linesi 200

SQL> select sql_text,sql_id,version_count,executions from v$sqlarea where sql_text like 'insert into t%';

 

SQL_TEXT                                 SQL_ID                     VERSION_COUNT EXECUTIONS

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

insert into t values(:n,:v)              21mycdpm39kzv                          4          6


利用查出来的sql_id查询v$sql_bind_capture,就能看到上述insert语句对应四个child cursor存储的绑定变量n和v的具体信息:


SQL> col sql_id for a15

SQL> col name for a10

SQL> col position for 999

SQL> col datatype_string for a15

SQL> col last_captured for a15

SQL> col value_string for a15

SQL> select sql_id,name,position,datatype_string,last_captured,value_string
         from v$sql_bind_capture where sql_id='21mycdpm39kzv';

 

SQL_ID          NAME   POSITION DATATYPE_STRING LAST_CAPTURED  VALUE_STRING

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

21mycdpm39kzv   :N           1 NUMBER

21mycdpm39kzv   :V           2 VARCHAR2(4000)

21mycdpm39kzv   :N           1 NUMBER

21mycdpm39kzv   :V           2 VARCHAR2(2000)

21mycdpm39kzv   :N           1 NUMBER

21mycdpm39kzv   :V           2 VARCHAR2(128)

21mycdpm39kzv   :N           1 NUMBER

21mycdpm39kzv   :V           2 VARCHAR2(32)

 

已选择 8 行。

可以看到绑定变量n和v在四个child cursor中列value_string的值都是null,说明Oracle确实不会捕获insert语句的values字句对应绑定变量的具体输入值。当然,awr repository对应数据字典表dba_hist_sqlstat和dba_hist_sqlbind也不会有上述绑定变量具体输入值。

此时如果进行flush shared_pool操作清空shared pool,在从视图v$sql_bind_capture中就查不到改动后的任何信息。但是还是可以从awr repository中对应数据字典中dba_hist_sqlstat和dba_hist_sqlbind查到绑定变量n和v具体捕获值。