Bir uygulama hata mesajı yükseltilemiyor

Hata ayıklama amacıyla, verilen bayrağa dayalı bir uygulama seviyesi mesajı yükseltmem gerekiyor. İşte istisna kodu

  EXCEPTION
    WHEN dml_errors THEN
      l_errors := SQL%BULK_EXCEPTIONS.COUNT;
      S_Publish('I', 'Number of statements that failed: ' || l_errors);
      FOR i IN 1..l_errors LOOP
         S_Publish('I', 'Error #' || TO_CHAR(i) || ' occurred during '|| 'iteration #' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
         S_Publish('I', 'Error message is ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
         S_Publish('I', 'Failing Record ID is ' || sap_tbl_ins(SQL%BULK_EXCEPTIONS(i).ERROR_INDEX).DEVICE_PIN);
      END LOOP;
      IF g_app_error_flag THEN
        raise_application_error(-20707, 'Fatal Error: Replication script exceptions', TRUE);
      END IF;

    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('Error on record:' || l_zzman);
      S_Publish('I', 'SAP_EQUI Update: Failure processing record ' || l_zzman);
      S_Publish ('F');
      IF g_app_error_flag THEN
        raise_application_error(-20708, 'Fatal Error: Replication script exceptions', TRUE);
      END IF;

Şimdi bu kod verildiğinde, raise_application_error , ** g_app_error_flag doğru olduğunda bir tane yükseltmelidir. Ancak, tüm durumlarda (senaryoyu kasıtlı olarak tabloya bir miktar kısıtlama ekleyerek kastettiğim test ortamı ile kast ediyorum) demek istediğim tek şey DML hatası yani.

ORA-01403: no data found 
ORA-06512: at "DBNAME.PRODUCT_COPY_PACKAGE", line 1808 
ORA-24381: error(s) in array DML 
ORA-06512: at "DBNAME.PRODUCT_COPY_PACKAGE", line 84 
ORA-06512: at line 3 

Neler olup bittiğini önerebilir misiniz?

P.S.:

S_Publish için tanım burada. S_Publish'da "yükseltme" yok.

  PROCEDURE S_Publish (i_type IN VARCHAR2, 
                         i_msg IN VARCHAR2 DEFAULT NULL) IS
  BEGIN

    CASE

       WHEN i_type = 'G' THEN
         IF g_debug_flag
         THEN
           INSERT INTO logtable (tstamp,line) values (SYSDATE, i_msg);
           COMMIT;
           g_counter := 0;
         END IF;

       WHEN i_type = 'F' THEN
         g_err_code  := SQLCODE;
         g_err_msg   := TO_CHAR(g_err_code)||' '||SUBSTR(SQLERRM, 1, 100);
         INSERT INTO logtable (tstamp,line) values (SYSDATE, g_err_msg);
         COMMIT;

       WHEN i_type = 'I' THEN
         INSERT INTO logtable (tstamp,line) values (SYSDATE, i_msg);
         COMMIT;
         g_counter := 0;

    END CASE;


  END S_Publish;

Küçük hata ayıklamadan sonra şu ana kadar anladım. Onun arkasında ne yendiğini bilmiyorum.

Bu yüzden sorun, programın yazdırma hatalarının sona ermesi değil, yani FOR i IN 1..l_errors LOOP 'da bitmesidir. Program END LOOP konumunda çıkar. Neden ondan sonra bir şey yürütülmüyor?

3
Kabul, ancak performans nedenleriyle, üretim ortamındaki hata ayıklama iletilerini azaltmak için bayraklar tanıtıldı. Doğru g_app_err_flag komut dosyası çağrıldığında DOĞRU değeri olarak gönderilir. Kodda g_app_error_flag doğru/yanlış ayarını yapan mantığı yoktur.
katma yazar x.509, kaynak
g_app_error_flag öğesinin TRUE olarak ayarlandığını nereden biliyorsunuz? Ve işlevsel olarak, bir istisna işleyicideki bir hata bayrağını kontrol etmenin anlamı nedir? Kuşkusuz, bir istisna işleyicisinde bulunmanız, uygulamanın bir hatayla karşılaştığını gösterir. Ek bir boolean bayrağının varlığı, herhangi bir bilgi eklemek değil, sadece ek hatalar için potansiyel yaratmak gibi görünüyor.
katma yazar Justin Cave, kaynak

3 cevap

Bu yüzden sorun S_Publish 'da idi. yani ifade ettiği tablo sap_tbl_ins , 0 tabanlıdır. SQL% BULK_EXCEPTIONS (i) .ERROR_INDEX temelde bu başarısız olduğunda yineleme numarasıdır. Bu nedenle, 0 tabanlı bir dizine bir sayı ile değinmek "sınır dışı dizi" istisnasını arttırıyor. Sadece anladım ve formülü değiştirdim

S_Publish('I', 'Failing Record ID is ' || sap_tbl_ins((SQL%BULK_EXCEPTIONS(i).ERROR_INDEX)-1).DEVICE_PIN);

ve iyi çalışıyor.

2
katma

Tamam, sorular:

1) PRODUCT_COPY_PKG içindeki 1808 satırındaki/etrafındaki kod nedir. Burası ilk hatanın alındığı yer.

2) Tomruklar eklenebilir durumda mı? (yani, bu istisna bloğu gerçekten çalışıyor mu?)

3) Bu hata yığını çıktısı dbms_output ifadelerinizden mi geliyor? Yoksa yığın çalışma zamanında Oracle’dan mı çıkıyor?

Stil notu: S_PUBLISH'in PRAGMA AUTONOMOUS_TRANSACTION ile tanımlanmış olduğunu umarım, aksi halde kodunuz hatalı durumdayken işlerin ortasındaysa, kısmen tamamlanmış bir işlem yapabilir.

0
katma

Kodun tamamını göremediğimizden, size senaryo üzerinde kasıtlı olarak bir kısıtlama ekleyerek kasıtlı olarak başarısızlığa uğradığınız zaman, güvenmek zorundayız, o zaman gönderdiğiniz bu İstisna bloğu aktif olandır. Bu yüzden bu blok devreye giriyorsa, "raise_application_error (-20707, ....." ya da -20708 ile ikinciyi görmemenizin bir nedeni, "S_Publish" prosedürünün bir istisna atması olabilir. Bu teoriyi sınamak için çağrıları geçici olarak silmeye çalışın ve hatalarınızı alıp almadığınızı görün.

0
katma
ju8st, orijinal testi S_PUBLISH tanımıyla güncelledi. S_PUBLISH ’de fırlatma istisnası yok.
katma yazar x.509, kaynak
Satır 1808, 3 değere sahip bir tabloya veri ekliyor, örneğin col1, col2, col3. Ancak, tablonun 4 sütunu vardır ve col4 üzerinde boş değil kısıtı vardır. Bunun istisnası atılıyor. Asıl soru, bu atılan istisnayı, diğerleri olduğunda istisna olarak yakalandı, ancak oradan açık bir şekilde artırıyor olmama rağmen, uygulama düzeyinde bir hata oradan ortaya çıkmıyor.
katma yazar x.509, kaynak
Bu yüzden sorun, programın yazdırma hatalarının sona ermesi değil, yani FOR i IN 1..l_errors LOOP 'da bitmesidir. Program END LOOP konumunda çıkar. Neden ondan sonra bir şey yürütülmüyor?
katma yazar x.509, kaynak
açıkça bir istisna atmak zorunda değildir. çalışırken bir istisna olabilir. ancak kodunu gönderdiğinizden beri, no_data_found istisnasını atmadığını sanıyorum çünkü içinde seçim cümleleri görmüyorum (ve başarısız olabilecek seçimleri olan günlük tablosuna yerleştirildikten sonra çalıştırılan hiçbir tetikleyiciyi sanırım). daha fazla kod gösterebilir misiniz (belki pastebin.com adresini kullanarak). özellikle "DBNAME.PRODUCT_COPY_PACKAGE", istisna oraya atılırken satır 1808 ". İstisna işleyiciniz istisnanın gerçekleştiği yeri kapsıyor mu?
katma yazar A.J., kaynak
Son bir şey: Seçtiğiniz bazı DBMS_OUTPUT.PUT_LINE dizesiyle "raise_application_error" ı değiştirin. işaretlenmiş görüyor musun?
katma yazar A.J., kaynak