2010-08-12 6 views
5

Wir sehen viele "ORA-00936: fehlende Ausdruck" -Fehler in unserem Anwendungsprotokoll. Gibt es einen Weg in Oracle, um festzustellen, welche Aussage (n) fehlschlagen?Oracle: Gibt es eine Möglichkeit, aktuelle SQL-Syntaxfehler zu erhalten?

Ich habe versucht, v $ sql abzufragen, aber diese Anweisungen werden nicht in diese Ansicht eingefügt, da sie die Syntaxprüfungen nicht bestehen.

Unsere C# -Anwendung verwendet Linq, um eine Abfrage an eine Oracle-Datenbank zu generieren. Dies macht es ein bisschen schwierig, die SQL-Abfrage von der Anwendung zu bekommen. Ich hatte gehofft, ich könnte es einfach von Oracle bekommen.

Antwort

5

Sie können einen Trigger in Oracle erstellen, die alle Fehler protokolliert (oder ziemlich all - NO_DATA_FOUND wird nicht als Fehler betrachtet. Im folgenden Beispiel wird jeder Fehler im Schema in der Tabelle TRACK_DETAIL aufgezeichnet (Fehler in einer Zeile, SQL im nächsten Fehler). Sie können mit einer Sequenznummer, Datum/Uhrzeit usw.

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; 
/

Denken Sie daran, fallen (oder deaktivieren) der Trigger es anspruchsvoller, wenn Sie mit ihm fertig sind.

+0

+1 Ich habe vergessen, Datenbank-Level-Trigger beim Schreiben meiner Antwort :( – ThinkJet

+0

Das ist genial. Ich hatte keine Ahnung, Sie könnten einen Trigger auf "servererror" erstellen! Danke! – CodingWithSpike

+0

Akzeptiert dies als die Antwort, weil es am besten für meine Situation funktionierte. Ich könnte in eine laufende DB gehen, den Trigger erstellen, den Fehler erhalten und den Trigger entfernen, ohne die Benutzer zu beeinflussen oder den App-Code erneut zu implementieren. – CodingWithSpike

1

Sie könnten versuchen, etwas wie Wireshark über den Port zu verwenden, der für die Verbindung mit Oracle verwendet wird, um zu sehen, welche SQL-Anweisungen gesendet werden. Vielleicht nicht die beste Antwort - aber es könnte Sie dorthin bringen, wo Sie schneller gehen müssen.

2

Wenn Sie die sql-Ablaufverfolgung aus dem Anwendungscode irgendwie aktivieren können (alter session set sql_trace = true), werden die Anweisungen in den Ablaufverfolgungsdateien auf dem Datenbankhost angezeigt.

1

Versuchen Sie SQL-Überwachungslösung von Kris Vandermotten blog.

Sie können auch log mit DataContext.Log property umleiten:

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

Oder nutzen Sie alle anderen Debugging-Tools wie LInQ to Entities Visualizer ...

+0

Ich habe nie bemerkt, dass Log-Eigenschaft dort war. Dank dafür! Technisch verwenden wir einen Linq Ausdruck gegen einen Entity Framework ObjectContext, nicht einen DataContext. Das war auch auf einem Server, wo ich keinen Zugriff hatte, um den Code zu ändern, daher wollte ich die Abfrage von Oracle holen. – CodingWithSpike