Как получить информацию о трассировке для переменных привязки, переданных через OracleParameter в ODP.NET?

Много погуглив и не найдя того, что ищу, я решил задать этот вопрос.

Я использую переменные привязки, как показано в этой замечательной статье 2005 под названием Обязательные ценности Марка А. Уильямса, например:

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.


person Leniel Maccaferri    schedule 21.09.2013    source источник


Ответы (2)


В качестве одного из вариантов вы можете включить трассировку sql с дампом переменных привязки, установив событие 10046 уровня 12 или 4 для сеанса вручную или автоматически (например, в триггере входа в систему для пользователя):

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 где 1234567 = :var ‹-- наш запрос
КОНЕЦ STMT
PARSE #375980232:c=0,e=375,p=0,cr= 0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=2640550034
BINDS #375980232:
Bind#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
person Nick Krasnov    schedule 21.09.2013
comment
Довольно милый Николай. Я читал об этих параметрах, но мне было любопытно узнать, есть ли отсутствующая/скрытая конфигурация, которая позволила бы мне получить информацию о привязке из коробки, используя стандартную трассировку ODP.NET. Они могли бы добавить новый уровень трассировки, чтобы показать эту информацию, не так ли? По крайней мере, у нас есть возможность получить эту информацию, и это здорово. Я попробую эти варианты как можно скорее. Большое спасибо! - person Leniel Maccaferri; 21.09.2013

Я согласен со всем, что написал Николас, но добавлю, что, начиная с Oracle 10.1, DBMS_MONITOR PL/SQL Package является предпочтительным методом включения/выключения трассировки. Хотя настройка события все еще работает, как прекрасно продемонстрировал Николас.

Как вы заметили, ODP не выдает значения переменных связывания в свой файл трассировки из соображений безопасности.

person Community    schedule 23.09.2013
comment
Большой! Я знаю, что этот ответ был предоставлен Марком А. Уильямсом (автор этой статьи, упомянутой в моем вопросе). Я связался с ним по электронной почте и попросил его поделиться своим мнением по этому вопросу. Он ответил на электронное письмо и сказал мне, что только что ответил на него. Какая я привилегированная! :D - person Leniel Maccaferri; 24.09.2013