Home / MAKALELER / Veri Tabanı / DML İşlemlerinde Hata Loglama

DML İşlemlerinde Hata Loglama

Bu makalede DML işlemlerinde istenmeyen hatalara karşı loglama yapılarak transactionın kesilmeden nasıl devam edeceği anlatılacaktır.

 

Standart bir şekilde yazılan DML işlemi yapan PL SQL bloglarında bir hata alınması sonucunda, DML’de başarılı bir şekilde işlem yapılan datanın kaç satır yapıldığı fark etmezsizin transaction rollback yapacaktır. Milyonca satır datanın içerisinde hatalı olan bir satır data bile olsa DML işlemi hata aldığı için işlem kesilecek ve ne olursa olsun transaction’da rollback yapılacaktır. Eğer hatalara rağmen DML işlemlerimiz devam etsin istiyorsak, DML error loglama yapılmalıdır. PL SQL bloguna eklenen loglama mekanizması ile DML işleminde hata alınsa bir hata satırı log tablosuna atılarak hatalar pas geçilir ve işlem devam ettirilir. Bu çoğu zaman hayat kurtaran bir işlem olacaktır. Log tablolarına bakılarak hatalı kayıtların datasal hataları gözden geçilerek gerekli işlemler yapılacaktır.

Oracle 10g R2 ile birlikte error logging özelliği geldi.   INSERT, UPDATE, DELETE ve MERGE işlemlerinde error logging özelliği eklendi. Böylece INSERT, UPDATE, DELETE ve MERGE hata alınsa bile işlem tamamlanıyordu. Şimdi örnekler ile bu konuyu daha iyi pekiştirelim. DML ifadesine eklediğimiz error loglama sytax inceleyelim.
LOG ERRORS INTO [sema.tablo] [(‘DML_ifadesi’)] [REJECT LIMIT limit_count/UNLIMITED]
LOG ERRORS ifadesi ile DML işlemlerinde error loglamayı aktif ediyoruz. INTO dan sonra hatalı kayıtların insert edileceği tabloyu gösteriyoruz. INTO kullanımı opsiyoneldir. Yani INTO kullanılmaz ise Oracle otomatik olarak error log tablosunu oluşturur ve isimlendirmesini ‘ERR$’ + substr(target_table_name,1,25) olarak yapar. ‘DML_ifadesi’ile hangi tip hataların loglama yapılacağını belirtiyoruz, bu ifade özellikle string olarak belirtilmelidir. REJECT LIMIT ile de kaç tane hataya kadar telaransımızın olduğunu belirtiyoruz. İstersek limit_count kadar bir limit verebiliriz yada hata kaç satır olursa olsun limitsiz bir şekilde loglama yapılmasını istiyorsakUNLIMITED kullanırız.
LOG ERRORS aktif olduktan sonra insert edilecek kayıtlar bir array’e aktarılıyor. Burada işlem iki aşamada devam ediyor. Birinci aşamada arraydan kayıtlar hedef tabloya insert ediliyor. Insert başarılı olursa array’a bir sonraki satırda olan veri geliyor, başarısız olursa ikinci aşamaya gecilip array’deki veri log tablosuna insert ediliyor ve sonraki satırdaki veri tekrar array’e gelerek geliyor. Tekrardan birinci aşamaya geçilmiş oluyor. İnsert işlemi son satıra kadar şu şekilde devam ediyor. Bu şekilde çalışmanın dezavantajı olarak insert işleminde süreler artıyor.
Kısıtlamalar
  •  Tablo üzerinde “DEFERRED” olarak tanımlanan constraints (kısıtlayıcılar) hata alınacaktır.
  •  Direct path INSERT veya MERGE işlemleri unique contstraitleri ve indeks hata alacaktır.
  • UPDATE ve MERGE işlemlerinde unique contstraitleri ve indeks hata alacaktır.
  • LONG ,LOB ve object type LOG ERRORS INTO de desteklenmez.
Şimdi yukarda anlattıklarımı örnekler üzerinde test ederek devam edelim. Öncelikle kendime basit bir kaynak tablo oluşturalım.
CREATE TABLE TEST_USER.TEST_SOURCE
(ID NUMBER,
CODE VARCHAR2(10),
DESCRIPTION VARCHAR2(50),
CONSTRAINT SOURCE_PK PRIMARY KEY(ID)
);
 Şimdi bu tabloyu basit bir senaryo ile dolduralım.
BEGIN
   EXECUTE IMMEDIATE ‘TRUNCATE TABLE TEST_USER.TEST_SOURCE’;
   FOR i IN1..100000
   LOOP
      IF i IN (1000,10000)
      THEN
         INSERT INTO test_user.test_source
              VALUES (i,NULL,’Description for ‘ || TO_CHAR(i));
      ELSE
         INSERT INTO test_user.test_source
              VALUES(i,TO_CHAR(i) || CHR(MOD(i,100)) || MOD(i,100),
                      ‘Description for ‘ || TO_CHAR(i));
      END IF;
   END LOOP;
  COMMIT;
   — Tablo istatistiklerini güncelleyelim
   DBMS_STATS.gather_table_stats (‘TEST_USER’,’TEST_SOURCE’,CASCADE=>TRUE);
END;
Şimdi hedef tablolarımızı oluşturalım.
CREATE TABLE TEST_USER.TARGET_TABLE (
 ID           NUMBER    NOT NULL,
 CODE         VARCHAR2(15) NOT NULL,
 DESCRIPTION VARCHAR2(50),
 CONSTRAINT TARGET_TABLE_PK PRIMARY KEY (ID)
);
CREATETABLE TEST_USER.TARGET_TABLE (
 ID           NUMBER    NOT NULL,
 CODE         VARCHAR2(15) NOT NULL,
 DESCRIPTION VARCHAR2(50),
 CONSTRAINT TARGET_TABLE_PK PRIMARY KEY (ID)
);
Target_table de Code kolonu üzerinde not null constraint konularak insertlerde null olan kayıtlar için hata alacağız. Aldığımız hataları log tablolarına göndereceğiz. Böylece işlem kesilmeden devam edecektir. Şimdi log tablosunu oluşturalım.
BEGIN
 DBMS_ERRLOG.create_error_log (err_log_table_owner =>’TEST_USER’, dml_table_name =>’TARGET_TABLE’);
END;
Şimdi DML işlemlerine başlayalım. İlk case insert olsun.
BEGIN
   INSERT INTO test_user.target_table
      SELECT *
        FROM test_user.source_table;
   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      ROLLBACK;
END;
Begin end blogu başarılı bir şekilde biter. Çünkü içersinde exception var. Yukarıdaki kod şu şekilde çalışır; insertler başlar, hata alır exceptiona düşer, exceptionda transaction rollback yapar, ve sonuç olarak source_tablo tablosuna hiç bir kayıt eklenmez.
select * from test_user.target_table;
no rows selected.
Aynı işlemi loglayarak yapalım.
BEGIN
   INSERT INTO test_user.target_table
      SELECT *
        FROM test_user.source_table
        LOG ERRORS INTO test_user.err$_target_table (‘INSERT’) REJECT LIMIT UNLIMITED;
   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      ROLLBACK;
END;
Target_table tablosunu kontrol edelim.
SELECT COUNT(*) AS COUNT FROM test_user.target_table;
 COUNT
———-
     99998
err$_target_table tablosunu kontrol edelim
SELECT COUNT(‘1’) AS COUNT FROM test_user.err$_target_table;
 COUNT
———-
         2
select ORA_ERR_MESG$ from test_user.err$_target_table;
ORA_ERR_MESG$
——————————————————————————
ORA-01400: cannot insert NULL into (“TEST_USER”.”TARGET_TABLE”.”CODE”)
ORA-01400: cannot insert NULL into (“TEST_USER”.”TARGET_TABLE”.”CODE”)
Şimdi Update işlemi yapalım.
BEGIN
   UPDATE test_user.target_table
      SET code = DECODE(ID,9,NULL,10,NULL, code + 1)
    WHERE ID BETWEEN 1 AND 10;
   COMMIT;
END;
Yukardaki kodu çalıştırdığımda hata alırım. Aldığım hata
ORA-01407: cannot update (“TEST_USER”.”TARGET_TABLE”.”CODE”) to NULL
ORA-06512: at line 3
Şimdi Updatede loglama yapalım.
BEGIN
   UPDATE test_user.target_table
      SET code =DECODE(ID,9,NULL,10,NULL, code +1)
    WHERE ID BETWEEN 1 AND 10
    LOG ERRORS INTO test_user.err$_target_table (‘UPDATE’) REJECT LIMIT UNLIMITED;
   COMMIT;
   EXCEPTION
   WHEN OTHERS
   THEN
      ROLLBACK;
END;
Yukarıdaki update işleminde bütün satırlarda hata alacaktır. err$_target_table tablosunu kontrol ettiğimde 10 kayıt görmeliyim.
SELECT COUNT(‘1’) AS COUNT
 FROM test_user.err$_target_table
 WHERE ora_err_tag$ =’UPDATE’;
 COUNT
———-
        10
 err$_target_table tablosuna bakalım. Kaç çeşit hata almışız.
SELECT   ora_err_mesg$,COUNT(‘1’) AS COUNT
    FROM test_user.err$_target_table
   WHERE ora_err_tag$ =’UPDATE’
GROUP BY ora_err_mesg$;
ORA_ERR_MESG$                                                                             COUNT
———————————————————————————————————————–
ORA-02292: integrity constraint (TEST_USER.DEST_CHILD_DEST_FK)
violated – child record found                                                                       10
 Tabloları silip temizlik yapalım.
DROP TABLE TEST_USER.TARGET_TABLE_CHILD CASCADE CONSTRAINTS;
DROP TABLE TEST_USER.TARGET_TABLE CASCADE CONSTRAINTS;
DROP TABLE TEST_USER.SOURCE_TABLE CASCADE CONSTRAINTS;
Bu makalede DML işlemlerinde hata loglaması nasıl yapılırı anlattım. Başka bir makalede tekrar birlikte olmak üzere, hoşçakalın.

 

About Ahmet Sedef

1986 yılı Yozgat doğumluyum. İlk, ortaokul ve lise eğitimimi Yozgat'ta tamamladım. 2010 yılında Yıldız Teknik Üniversitesi İstatistik Bölümünden mezun oldum. Lisans eğitimim süresinde Türkiye istatistik Kurumu ve SAS Türkiye'de staj yaptım. Kariyerime iş zekası alanında devam ediyorum. İlgi Alanımlarım; Oracle, MS SQL Server, PL/SQL, T-SQL, Java,JavaScript,Informatica PowerCenter, Oracle Data Integrator,Datastage, Diğer ETL toolları, Hyperion EPM, OBIEE

İlginizi Çekebilir

SQL Server ile Veri Şifreleme

Bilgi teknolojilerinde verinin güvenliği çok kritik bir öneme sahiptir. Önemli verileri korumak için ekstra bir …

Bir Cevap Yazın