2013-04-24 19 views
6

PL/SQL veya SQL'de bir Dinamik SQL deyimindeki bir hatanın konumunu nasıl bulabilirim? SQL itibarenOracle: SQL veya PL/SQL kullanarak dinamik SQL'de bir hatanın konumunu bulma

* Artı ben örneğin, geçersiz bir SQL DML deyimi, bir hata konumunu bakın:

[email protected]> SELECT 
     2 X 
     3 FROM 
     4 TABLEX 
     5/
    TABLEX 
    * 
ERROR at line 4: 
ORA-00942: table or view does not exist 

SQL * Plus, satır numarası ile hata gösterir ve baskılar ve çizgi işaretleri hatanın bulunduğu bir yıldızla.

Dinamik SQL dönüştürülüyor, ben hata kodunu (sqlcode) ve hata mesajı (SQLERRM) alabilirsiniz:

[email protected]> SET SERVEROUTPUT ON 
[email protected]> BEGIN 
     2 EXECUTE IMMEDIATE 'SELECT X FROM TABLEX'; 
     3 EXCEPTION 
     4 WHEN OTHERS THEN 
     5  DBMS_OUTPUT.PUT_LINE('SQLCODE:' || SQLCODE); 
     6  DBMS_OUTPUT.PUT_LINE('SQLERRM:' || SQLERRM); 
     7 END; 
     8/
SQLCODE:-942 
SQLERRM:ORA-00942: table or view does not exist 

Ama nasıl Dinamik SQL dizede hata pozisyonunu alabilirim?

Oracle'ın bir hata hakkında ilginç bilgiler içeren bir SQL İletişim Alanı (SQLCA) sağladığını görüyorum. Özellikle:

  • sqlcode ve SQLERRM alanları SQLERRD (5) elemanı verir
  • SQLERRD alanı (yani, ilgili PL/SQL fonksiyonları ile alınan verilerin kaynağı olabilir) ' ayrıştırma hatası.

SQLERRD'ye PL/SQL veya SQL'den erişmek mümkün mü? Öyleyse nasıl? Değilse, başka hangi yöntem PL/SQL veya SQL'den hatanın yerini verebilir?

(Burada http://docs.oracle.com/cd/B28359_01/appdev.111/b31231/chapter8.htm#BABIGBFF SQLCA belgelenmiştir ve Pro * C ile erişilen.)

(cevap burada how to declare SQLCA.SQLERRD? o SQLERRD PL/SQL tanımlanmış ve bu nedenle erişilebilir değildir işaret gibi görünüyor.)

(Buradaki tartışma, Why doesn't Oracle tell you WHICH table or view does not exist?, trace dosyalarını kullanarak ve bazı geliştirme araçlarındaki hataların yerini göstermek için kötü SQL'i gösterecek bazı önerilerde bulunur.)

cevap

1

Deyimi dinamik PL/SQL aracılığıyla çalıştırmak, ilgili satır numarasını hata yığınında saklar . Örneğin

, bu açıklama 4. hatta bir hata var:

declare 
    v_count number; 
    v_bad_sql varchar2(32767) := 
     'SELECT 
      X 
      FROM 
      TABLEX'; 
begin 
    execute immediate v_bad_sql into v_count; 
exception when others then 
    begin 
     execute immediate 
      'begin for i in ('||v_bad_sql||') loop null; end loop; end;'; 
    exception when others then 
     dbms_output.put_line(sqlerrm); 
    end; 
end; 
/

ORA-06550: line 4, column 4: 
PL/SQL: ORA-00942: table or view does not exist 
ORA-00942: table or view does not exist 
ORA-06550: line 1, column 18: 
PL/SQL: SQL Statement ignored 
ORA-00942: table or view does not exist 

bu yöntem bazı dezavantajları vardır:

  1. Bu durum ve yeniden yakalamak için bazı ekstra, çirkin kod gerektirir -SQL'i dene.
  2. Örnek, yalnızca seçimler için çalışır. Eklemek, güncelleştirmek, düzeltmek, birleştirmek, dinamik PL/SQL, vb. Için değiştirmeniz gerekir. Normalde ne tür bir SQL ifadesi olduğunu bilmelisiniz. Eğer şanssızsanız, ifadeyi ayrıştırmanız gerekir ki bu çok zor olabilir.
  3. Tüm PL/SQL ifadesi bir satırdaysa sütun numarası yanlış.
+0

Ben SQL davranışını * taklit çalışıyorum hata iletileri ayıklanması için Artı kusurlu hattı ve işaretlemek başka bir hat yazdırarak bir paket geldi sorunla başlangıcıdır yıldız işareti. Çizgi ve sütun sayısını almak için hata kümesini ayrıştırmakla ihtiyacım olanı alabilirim, ancak daha kolay bir yol var mı? –

+0

Bildiğim kadarıyla daha kolay bir yol yok. –

3

Eğer dbms_utility

begin 
    .. generate error 
exception when others then 
    dbms_output.put_line(
     dbms_utility.format_call_stack()  || chr(10) || 
     dbms_utility.format_error_backtrace() || chr(10) || 
     dbms_utility.format_error_stack()) 
end; 
+2

Örnekle SQL fiddle: http://www.sqlfiddle.com/#!4/471dd/1 – ThinkJet

+1

DBMS_UTILITY kendi başına dinamik bir SQL ifadesi * içinde * satır numarasını bulmak için yeterli değildir. Yine de, SQL'in dinamik bir SQL bloğunda sarılmasının zorluğu olsa da, ThinkJet'in ikinci bloğu çalışacaktır. (İlk blok her zaman çalışmaz - ayrıştırma hataları için doğru satır numaralarını alamaz, örneğin tablo adı yanlışsa). –