2010-08-12 1 views
5

Мы видим много ошибок «ORA-00936: недостающее выражение» в нашем журнале приложений. Есть ли способ в Oracle определить, какие утверждения (ы) терпят неудачу?Oracle: Есть ли способ получить последние синтаксические ошибки SQL?

Я пробовал запросить v $ sql, но эти утверждения не вставляются в это представление, так как они не проходят проверки синтаксиса.

Наше приложение C# использует Linq для генерации запроса в базу данных Oracle. Это затрудняет получение запроса sql из приложения. Я надеялся, что могу просто получить это от Oracle.

ответ

5

Вы можете создать триггер в Oracle, который будет регистрировать все ошибки (или в значительной степени all - NO_DATA_FOUND не считается ошибкой). В приведенном ниже примере любая ошибка в схеме записывается в таблицу TRACK_DETAIL (ошибка в одной строке, неудачный SQL в следующем). Вы можете сделать его более сложным с порядковым номером, дата/время и т.д.

create table track_detail (val varchar2(4000)); 

create or replace procedure track (p_text IN VARCHAR2) IS 
    PRAGMA AUTONOMOUS_TRANSACTION; 
begin 
    insert into track_detail(val) 
    values (p_text); 
    commit; 
end; 
. 
/
create or replace TRIGGER log_err after servererror on schema 
DECLARE 
    v_temp VARCHAR2(2000) := substr(dbms_utility.format_error_stack,1,2000); 
    v_num NUMBER; 
    v_sql_text ora_name_list_t; 
begin 
    v_temp := translate(v_temp,'''','"'); 
    track(v_temp); 
    v_num := ora_sql_txt(v_sql_text); 
    v_temp := null; 
    BEGIN 
    FOR i IN 1..v_num LOOP 
     v_temp := v_temp || v_sql_text(i); 
    END LOOP; 
    EXCEPTION 
    WHEN VALUE_ERROR THEN NULL; 
    END; 
    v_temp := translate(v_temp,''''||chr(0)||chr(10),'"'); 
    track(v_temp); 
end; 
/

Помните падение (или отключить) триггера, когда вы закончили с ним.

+0

+1 Я забыл о триггерах уровня базы данных при написании своего ответа :( – ThinkJet

+0

Thats awesome. Я понятия не имел, что вы можете создать триггер на «servererror»! Спасибо! – CodingWithSpike

+0

Принимал это как ответ, потому что он лучше всего работал для моей ситуации. Я мог бы зайти в исполняемую базу данных, создать триггер, получить ошибку и удалить триггер без использования пользователей или перераспределить код приложения. Спасибо, Гэри! – CodingWithSpike

1

Вы можете попробовать использовать что-то вроде Wireshark в порту, используемом для подключения к Oracle, чтобы увидеть, какие SQL-запросы отправляются. Возможно, это не лучший ответ, но он может помочь вам, когда вам нужно идти быстрее.

2

Если вы можете каким-либо образом включить SQL-трассировку из кода приложения (изменить набор сеансов sql_trace = true), операторы будут отображаться в файлах трассировки на узле базы данных.

1

Попробуйте решение для мониторинга SQL от Kris Vandermotten blog.

Также вы можете перенаправить журнал с DataContext.Log property:

using (NorthwindDataContext context = new NorthwindDataContext()) 
{ 
    context.Log = Console.Out; 
} 

Или использовать любые другие отладочные инструменты, такие как LInQ to Entities Visualizer ...

+0

Я никогда не понимал, что свойство Log существует. Спасибо за это! Технически мы используем выражение Linq для Object Entity Framework ObjectContext, а не для DataContext. Это было также на сервере, так как у меня нет доступа к изменению кода, поэтому я хочу получить запрос от Oracle. – CodingWithSpike

Смежные вопросы