2010-08-12 14 views
5

Stiamo riscontrando un sacco di errori "ORA-00936: espressione mancante" nel nostro registro applicazioni. C'è un modo in Oracle per determinare quali affermazioni stanno fallendo?Oracle: esiste un modo per ottenere errori di sintassi SQL recenti?

Ho provato a interrogare v $ sql, ma queste istruzioni non sono inserite in quella vista, poiché non passano i controlli di sintassi.

La nostra applicazione C# sta utilizzando Linq per generare una query su un database Oracle. Ciò rende un po 'difficile ottenere la query sql dall'applicazione. Speravo di poterlo ottenere da Oracle più facilmente.

risposta

5

È possibile creare un trigger in Oracle che registrerà tutti gli errori (o quasi all - NO_DATA_FOUND non è considerato un errore). Nell'esempio seguente, qualsiasi errore nello schema è registrato nella tabella TRACK_DETAIL (errore in una riga, SQL fallito nel prossimo). È possibile rendere più sofisticato, con un numero di sequenza, data/ora ecc

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

Ricordate di eliminare (o disattivare) il grilletto quando hai finito con esso.

+0

+1 Ho dimenticato i trigger a livello di database mentre scrivevo la mia risposta :( – ThinkJet

+0

Questo è fantastico, non avevo idea di poter creare un trigger su "servererror"! Grazie! – CodingWithSpike

+0

Ho accettato questa risposta perché funzionava meglio per la mia situazione. Potrei entrare in un DB in esecuzione, creare il trigger, ottenere l'errore e rimuovere il trigger senza influenzare gli utenti o ridistribuire il codice dell'app. Grazie Gary! – CodingWithSpike

1

Si potrebbe provare a utilizzare qualcosa come Wireshark sulla porta utilizzata per connettersi a Oracle per vedere quali istruzioni SQL vengono inviate. Potrebbe non essere la migliore risposta - ma potrebbe portarti dove devi andare più veloce.

2

Se è possibile abilitare la traccia sql dal codice dell'applicazione in qualche modo (alterare la sessione set sql_trace = true), le istruzioni verranno visualizzate nei file di traccia sull'host del database.

1

Provare soluzione di monitoraggio SQL da Kris Vandermotten blog.

Inoltre è possibile reindirizzare log con DataContext.Log property:

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

sia in altro strumenti di debug come LInQ to Entities Visualizer ...

+0

Non ho mai realizzato che la proprietà del registro fosse lì. Grazie per quello! Tecnicamente stiamo usando un'espressione Linq contro un ObjectContext di Entity Framework, non un DataContext. Questo era anche su un server dove non avevo accesso per cambiare il codice, quindi volevo prendere la query da Oracle. – CodingWithSpike

Problemi correlati