2010-08-12 33 views
5

Uygulama günlüğümüzde çok fazla "ORA-00936: eksik ifade" hatası görüyoruz. Hangi ifadelerin başarısız olduğunu belirlemek için Oracle'da bir yol var mı?Oracle: Son SQL sözdizimi hatalarını almanın bir yolu var mı?

V $ sql'yi sorgulamayı denedim, ancak sözdizimi denetimlerini geçmediği için bu ifadeler bu görünüme eklenmiyor.

C# uygulamamız, bir Oracle veritabanına bir sorgu oluşturmak için Linq kullanıyor. Bu, sql sorgusunu uygulamadan almak için biraz zor hale getirir. Sadece Oracle'dan daha kolay alabileceğimi umuyordum.

cevap

5

Hepiniz hataları kaydedeceği Oracle bir tetikleyici oluşturun (veya hemen hemen tüm ...

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

Ya LInQ to Entities Visualizer gibi başka ayıklama araçları kullanın:

Ayrıca DataContext.Log property ile günlüğünü yönlendirebilirsiniz all - NO_DATA_FOUND bir hata olarak kabul edilmez). Aşağıdaki örnekte şemadaki herhangi bir hata TRACK_DETAIL tablosuna kaydedilir (bir satırdaki hata, sonraki SQL'de başarısız oldu). Sen vs bir sıra numarası, tarih/saat

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

damla unutmayın (veya devre dışı bırakmak) onunla bitirdikten tetikleyici ile daha sofistike yapabilirsiniz.

+0

+1 Yanıtı yazarken veritabanı düzeyindeki tetikleyicileri unuttum :( – ThinkJet

+0

Thats awesome. "Servererror" üzerinde bir tetikleyici oluşturabileceğine dair hiçbir fikrim yoktu! Teşekkürler! – CodingWithSpike

+0

Durumum için en iyi şekilde çalıştığı için bunu yanıt olarak kabul ettim. Çalışan bir DB'ye girebilir, tetikleyiciyi oluşturabilir, hatayı alabilir ve kullanıcıları etkilemeden ya da uygulama kodunu yeniden değiştirmeden tetikleyiciyi kaldırabilirim. – CodingWithSpike

1

SQL ifadeleri gönderilmek üzere Oracle'a bağlanmak için kullanılan bağlantı noktasında Wireshark gibi bir şey kullanmayı deneyebilirsiniz. En iyi cevap olmayabilir - ama size daha hızlı gitmeniz gereken yere sahip olabilir.

2

Uygulama kodundan sql izlemeyi bir şekilde etkinleştirirseniz (sql_trace = true oturum kümesini değiştirir), deyimler veritabanı ana bilgisayarındaki izleme dosyalarında görünür.

1

SQL izleme çözümünü Kris Vandermotten blog'dan deneyin.

+0

Log özelliklerinin orada olduğunu hiç fark etmemiştim. Bunun için teşekkürler! Teknik olarak bir DataContext değil, bir Entity Framework ObjectContext'e karşı bir Linq ifadesi kullanıyoruz. Bu aynı zamanda bir sunucu üzerinde kod değiştirmek için erişimim yoktu, bu yüzden Oracle'dan sorguyu almak istedim. – CodingWithSpike

İlgili konular