перехватить текст упавшего SQL-запроса по ошибке?

ORAngutang
Дата: 27.11.2009 19:08:15
Есть некий недоступный (из программы с закрытым кодом) SQL-запрос, один SUB-Select cтал (из за проблемы с данными) возвращать более 1-й строчки! Запрос падает, ошибка ОRA-XXXX предстаёт пред светлы очи юзера. Вопрос - как отловить текст запроса по (скажем по AFTER-ERROR триггеру)
Есть у кого-то готовый пример?

____________________________________________________________
сейчас работаю на: Oracle 11.1.0.7.0, 64bit, standard edition, SLES-10. APEX 3.2
suPPLer
Дата: 27.11.2009 19:13:22
ORAngutang,

а трассировка не спасёт?
andrey_anonymous
Дата: 27.11.2009 20:22:41
ORAngutang
Запрос падает, ошибка ОRA-XXXX предстаёт пред светлы очи юзера. Вопрос - как отловить текст запроса по (скажем по AFTER-ERROR триггеру)

Установить event ХХХХ и смотреть выпавшие трейсы не катит?
leader
Дата: 28.11.2009 00:47:47
ORAngutang,

воспользоваться утилитой SQLMonitor
советчегг
Дата: 28.11.2009 13:02:39
ORAngutang
Запрос падает, ошибка ОRA-XXXX предстаёт пред светлы очи юзера. Вопрос - как отловить текст запроса


поставь event и сотри user_dump_dest

ALTER SYSTEM SET EVENTS 'XXXXX trace name errorstack level 3';
Тынц.
Дата: 28.11.2009 13:45:45
ORAngutang
Есть некий недоступный (из программы с закрытым кодом) SQL-запрос, один SUB-Select cтал (из за проблемы с данными) возвращать более 1-й строчки! Запрос падает, ошибка ОRA-XXXX предстаёт пред светлы очи юзера. Вопрос - как отловить текст запроса по (скажем по AFTER-ERROR триггеру)
Есть у кого-то готовый пример?

____________________________________________________________
сейчас работаю на: Oracle 11.1.0.7.0, 64bit, standard edition, SLES-10. APEX 3.2

create or replace trigger log_errors_trg
after servererror on schema
declare
 v_sql_text ora_name_list_t;
 v_msg varchar2(4000);
 v_sql varchar2(4000);
 n int;
 cr varchar2(1) := chr(10);
begin
  for i in 1..ora_server_error_depth loop
    v_msg := v_msg || substr(ora_server_error_msg(i),1,4000-nvl(length(v_msg),0));
  end loop;

  n := ora_sql_txt(v_sql_text);
  for i in 1..n loop
     v_sql := v_sql || substr(v_sql_text(i),1,4000-nvl(length(v_sql),0));
  end loop;

  v_msg := trim(both chr(0) from v_msg);
  v_sql := trim(both chr(0) from v_sql);

  execute immediate
  'declare pragma autonomous_transaction;'||cr||
  'begin'||cr||
  '  insert into errors_log(err_date,err_code,message,sqltext,err_stack,call_stack)'||cr||
  '  values (sysdate,:p_err,:p_msg,:p_sql,:p_error_stack,:p_call_stack);'||cr||
  '  commit;'||cr||
  'end;'
  using ora_server_error(1), v_msg, v_sql
  , substr(dbms_utility.format_error_stack,1,4000), substr(dbms_utility.format_call_stack,1,4000);
end;
SY
Дата: 28.11.2009 14:52:56
Тынц.


And changing it to CLOB would allow to get complete SQL and will simplfy things a bit. Also, last time I checked dbms_utility.format_call_stack and dbms_utility.format_error_stack return varchar2 up to 2000 bytes, so there is no need to substr:

create or replace trigger log_errors_trg
after servererror on schema
declare
 v_sql_text ora_name_list_t;
 v_msg CLOB;
 v_sql CLOB;
 n int;
begin
  for i in 1..ora_server_error_depth loop
    v_msg := v_msg ||ora_server_error_msg(i);
  end loop;

  n := ora_sql_txt(v_sql_text);
  for i in 1..n loop
     v_sql := v_sql || v_sql_text(i);
  end loop;

  v_msg := trim(both chr(0) from v_msg);
  v_sql := trim(both chr(0) from v_sql);

  execute immediate
  'declare pragma autonomous_transaction;
   begin
     insert into errors_log(err_date,err_code,message,sqltext,err_stack,call_stack)
     values (sysdate,:p_err,:p_msg,:p_sql,:p_error_stack,:p_call_stack);
     commit;
   end;'
  using ora_server_error(1), v_msg,v_sql,dbms_utility.format_error_stack,dbms_utility.format_call_stack;
end;
Тынц.
Дата: 28.11.2009 15:23:40
SY

And changing it to CLOB would allow to get complete SQL and will simplfy things a bit.

Понятно, если стоит задача отловить SQL целиком или используемое приложение генерирует многоярусные запросы, то без clob'a не обойтись.
Тут триггер писался для того, чтобы можно было найти место начала раскопок после обращений пользователей в запущенных случаях, когда информации о проблеме минимум ("У нас тут на прошлой неделе ошибка какая-то была, исправьте, пожалуйста."). Как правило, собранной информации достаточно (ещё с десяток полей заполняется default'ами из userenv + специфической информацией контекста приложения), да и обращаться к такому логу приходится довольно редко.
SY

Also, last time I checked dbms_utility.format_call_stack and dbms_utility.format_error_stack return varchar2 up to 2000 bytes, so there is no need to substr:

Это от привычки "надеясь на лучшее, готовиться к худшему", отталкивался о таблицы. Насчёт 2000 - не обращал внимания, но когда-нибудь при "разборе полётов" пришлось бы столкнуться, спасибо за инфо :)