4

在谷歌搜索了很多并没有找到我要找的东西之后,我决定问这个问题。

我正在使用绑定变量,正如2005 年的这篇很棒的文章所展示的那样,Mark A. Williams 的标题为绑定的值,如下所示:

OracleParameter p_APP_NAME =
    new OracleParameter("p_APP_NAME", OracleDbType.NVarchar2, ParameterDirection.Input);
                         p_APP_NAME.Size = 50;
                         p_APP_NAME.Value = log.Application.Name;
                         cmd.Parameters.Add(p_APP_NAME);

我成功地启用了ODP.NET调试跟踪,但缺少的一个关键信息是日志SQL statement没有显示绑定到绑定变量的值是什么。

它正在记录OracleCommand.CommandText但没有OracleCommand.Parameters值。它向我展示了这个:

TIME:2013/09/20-22:59:21:890 TID:20fc  OpsSqlPrepare2(): SQL: UPDATE PS_LOG SET 
                                              APP_NAME = :p_APP_NAME, 
                                              WHERE LOG_ID = :p_LOG_ID

我真正想看到的是发送到 ORACLE 服务器的查询中使用的实际值,如下所示:

TIME:2013/09/20-22:59:21:890 TID:20fc  OpsSqlPrepare2(): SQL: UPDATE PS_LOG SET 
                                              APP_NAME = 'App Name', 
                                              WHERE LOG_ID = 777

我是否缺少某些配置,或者在使用ODP.NET跟踪功能时我想要的信息不可用?

如果这不是内置的,我想我将不得不实现自己的替换方法并SQL Statement自己记录。

4

2 回答 2

7

作为选项之一,您可以通过手动或自动(例如在用户的登录触发器中)为会话设置级别 12 或 4 的 10046 事件来打开带有绑定变量转储的 sql 跟踪:

alter session set events '10046 trace name context forever, level 12';

之后,将在参数指定的目录中生成跟踪文件user_dump_dest

SQL> show parameter user_dump_dest;

NAME                                 TYPE        VALUE                          
------------------------------------ ----------- ------------------------------ 
user_dump_dest                       string      D:\...\diag\rdbms\cdb\cdb 
                                                 \trace   

这是一个例子:

SQL> alter session set events '10046 trace name context forever, level 12';
  2 variable var number;
  3 exec :var := 1234567;     -- our bind variable
  4 select 1 from dual where 1234567 = :var ;

在新生成的跟踪文件中提供的其他信息中,我们可以找到有关查询、绑定变量及其值的信息:

解析光标#375980232 len=40 dep=0 uid=103
oct=3 lid=103 tim=2640550035 hv=1641534478
ad='7ff5bd0baf0' sqlid='ap9rzz5hxgp0f'
select 1 from dual where 1234567 = :var <-- 我们的查询
STMT 解析结束
#375980232:c=0,e=375,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=2640550034绑定
#375980232:
绑定#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=03 fl2=1000000 frm=01 csi=178 siz=24 off=0
kxsbbbfp=16646e10 bln =22 avl=05 flg=05
value=1234567 <--绑定变量的值

您还可以从 Oracle 10g 及更高版本开始查询v$sql_bind_capture动态性能视图以获取有关绑定变量及其值的信息:

select t.parsing_user_id
     , t.sql_fulltext         -- text of a query
     , bc.name                -- name of a bind variable
     , bc.value_string        -- value of a bind variable
  from v$sqlarea t
  join v$sql_bind_capture bc
    on (bc.sql_id = t.sql_id)
  join v$session s
    on (s.user# = t.parsing_schema_id)
  where s.username = user
    and bc.name in (':VAR') -- name of a bind variable(s), 
                            -- value(s) of which we want to know

结果:

PARSING_USER_ID   SQL_FULLTEXT                      NAME    VALUE_STRING   
 ------------------------------------------------------------------------ 
           103   select 1 from dual where 1 =:var  :VAR     1234567
于 2013-09-21T07:21:31.517 回答
2

我同意 Nicholas 发布的所有内容,但要补充一点,从 Oracle 10.1 开始,DBMS_MONITOR PL/SQL 包是启用/禁用跟踪的首选方法。尽管 Nicholas 已经很好地证明了设置事件仍然有效。

正如您所观察到的,出于安全考虑,ODP 不会将绑定变量值发送到其跟踪文件中。

于 2013-09-23T21:09:47.877 回答