2016-04-20 8 views
0

ich mich gefragt, ob es einen Weg gibt dynamische SQL-Anweisungen, deren Ausführung brach während der Laufzeit zu finden, falls es keine richtige Ausnahme war in der/SQL-Programmeinheit PL Handhabung, die die Dynanic genannt SQL.Finden schlechte dynamische SQL-Anweisungen enthält Syntaxfehler in Oracle

procedure will_crash is 
begin 
    -- 1000 dynamic sql statements here .. 

    execute immediate 'updaXte dual set X = ''Z'' ' ; 

    -- ... and 1000 more dynamic sql statements here .. 
    commit; 
end; --> NO proper exception handling for logging the last sql statement 

Falls eine programmierte Nachtzeiteinheit Hunderte von dynamischen SQL-Anweisungen enthält, würde ich gerne herausfinden, welche ohne Debugging kaputt gegangen ist. Protokolliert Oracle irgendetwas in seinen Systemansichten?

+1

Definieren Sie "pleite". Höchstwahrscheinlich, nein. Wenn es sich um einfache Syntaxfehler handelt, wird dies nicht protokolliert. Wenn die geplante "Nachtzeit-Programmeinheit" über die Datenbank geplant wird und der Fehler bis zum Aufrufer weitergegeben wird, wird der Fehler-Stack protokolliert (abhängig davon, welchen Zeitplanungsmechanismus Sie verwenden). Diese Stack-Ablaufverfolgung würde eine Zeilennummer enthalten, die Ihnen dabei helfen könnte, anzunehmen, dass Sie tatsächlich Tausende von Codezeilen haben, anstatt eine Schleife zu erstellen, die Tausende von verschiedenen SQL-Anweisungen erstellt. –

+0

Vielleicht hilft das? https://oracle-base.com/articles/10g/dml-error-logging-10gr2 – OldProgrammer

+0

ich mein Paket mit execute_immediate Verfahren verwenden - Wrapper um DBMS_SQL/sofort auszuführen. Es verfügt über Buildin-Protokollierung von SQL-Text vor der Ausführung, Ausführungszeit, sql% rowcount und explain_plan nach der Ausführung. Im Fehlerfall protokolliert es Fehlerstack, Code usw. – Rusty

Antwort

0

In Sie sind Beispiel gibt es keine Notwendigkeit an alle dynamischen SQL zu verwenden, so dass die einfachste Lösung ist es neu zu schreiben als

procedure will_crash is 
begin 
    -- 1000 dynamic sql statements here .. 

    updaXte dual set X = ''Z''; -- Error at compile time!! 

    -- ... and 1000 more dynamic sql statements here .. 
    commit; 
end; --> NO proper exception handling for logging the last sql statement 

Wenn die reale Prozedur dynamische SQL verwendet, weil die SQL-Anweisungen an anderer Stelle gespeichert werden (Variablen oder SQL-Tabelle), und wir sprechen nur über Syntaxfehler, können Sie Ihr Ziel erreichen, bevor Sie Anweisungen mit DBMS_SQL-Paket ausführen. Hier ist ein Beispiel:

DECLARE 

    lc_good VARCHAR2(200) := 'SELECT 1 FROM dual'; 
    lc_bad VARCHAR2(200) := 'SEL1ECT a FROM dual'; 
    lc_cursor NUMBER; 

BEGIN 

    lc_cursor := SYS.DBMS_SQL.OPEN_CURSOR; 

    BEGIN 
     SYS.DBMS_SQL.PARSE(lc_cursor, lc_good, DBMS_SQL.V7); 
     dbms_output.put_line('Statement 1 is GOOD'); 
    EXCEPTION 
     WHEN OTHERS THEN 
      dbms_output.put_line('Statement 1 is BAD: ' || SQLERRM); 
    END; 

    BEGIN 
     SYS.DBMS_SQL.PARSE(lc_cursor, lc_bad, DBMS_SQL.V7); 
     dbms_output.put_line('Statement 2 is GOOD'); 
    EXCEPTION 
     WHEN OTHERS THEN 
      dbms_output.put_line('Statement 2 is BAD: ' || SQLERRM); 
    END; 

    SYS.DBMS_SQL.close_cursor(lc_cursor); 

END; 

Der Funktionsausgang ist die folgend:

Statement 1 is GOOD 
Statement 2 is BAD: ORA-00900: ... 

Beachten Sie, dass der Code nur die SQL-Anweisungen analysiert, es zu tun führt sie nicht.