Menangani PL/SQL Errors

7.9. Tip-tip Menangani PL/SQL Errors

Pada bagian ini, kita akan mempelajari tiga teknik yang dapat meningkatkan fleksibilitas.

7.9.1. Melanjutkan Setelah Sebuah Exception Muncul

Sebuah exception handler mengijinkan kita untuk memperbaiki dari sebuah fatal error yang lain sebelum keluar dari blok. Namun ketika handler tersebut selesai, blok tersebut diakhiri. Dari sebuah exception handler, kita tidak dapat kembali ke blok terkini. Dalam contoh beirkut ini, jika perintah SELECT INTO menyebabkan munculnya ZERO_DIVIDE, kita tidak dapat melanjutkan dengan perintah INSERT:

DECLARE
  pe_ratio NUMBER(3,1);
BEGIN
  DELETE FROM stats WHERE symbol = 'XYZ';
  SELECT price / NVL(earnings, 0) INTO pe_ratio FROM stocks
  WHERE symbol = 'XYZ';
  INSERT INTO stats (symbol, ratio) VALUES ('XYZ', pe_ratio);
  EXCEPTION
    WHEN ZERO_DIVIDE THEN
      ...
END;

Kita tetap dapat menangani sebuah exception untuk sebuah perintah, kemudian melanjutkan dengan perintah selanjutnya. Tempatkan perintah tersebut di dalam sub-blok miliknya sendiri dengan exception handlers-nya sendiri. Jika sebuah error timbul di dalam sub-blok tersebut, sebuah local handler dapat menangkap exception tersebut. Ketika sub-blok tersebut berakhir, blok yang melingkupinya dapat terus berjalan pada titik dimana sub-blok tersebut berakhir. Mari kita perhatikan contoh berikut ini:

DECLARE
  pe_ratio NUMBER(3,1);
BEGIN
  DELETE FROM stats WHERE symbol = 'XYZ';
  BEGIN ---------- sub-blok mulai
    SELECT price / NVL(earnings, 0) INTO pe_ratio FROM stocks
    WHERE symbol = 'XYZ';
    EXCEPTION
      WHEN ZERO_DIVIDE THEN
        pe_ratio := 0;
  END; ---------- sub-blok selesai
  INSERT INTO stats (symbol, ratio) VALUES (’XYZ’, pe_ratio);
  EXCEPTION
    WHEN OTHERS THEN
      ...
END;

Dalam contoh ini, jika perintah SELECT INTO menyebabkan sebuah ZERO_DIVIDE exception, local handler menangkapnya dan mengatur pe_ration ke nol. Eksekusi dari handler tersebut selesai, sehingga sub-blok berakhir, dan eksekusi dilanjutkan dengan perintah INSERT.

Kita juga dapat melakukan rangkaian operasi-operasi DML dimana beberapa dapat gagal, dan memproses exceptions hanya setelah seluruh operasi selesai.

7.9.2. Mencoba Kembali Sebuah Transaksi

Setelah sebuah exception muncul, dibandingkan membuang transaksi kita, kita mungkin ingin mencobanya kembali. Tekniknya adalah:

  1. Masukkan transaksi ke dalam sebuah sub-blok.
  2. Tempatkan sub-blok di dalam sebuah loop yang mengulang transaksi.
  3. Sebelum memulai transaksi, tandai sebuah savepoint. Jika transaksi tersebut berhasil, lakukan commit, kemudian keluar dari loop. Jika transaksi gagal, kontrol berpindah ke exception handler, dimana kita melakukan roll back ke savepoint dan membatalkan seluruh perubahan dan kemudian mencoba memperbaikai masalah

Mari kita perhatikan contoh di bawah ini. Ketika exception handler selesai, sub-blok berakhir, kontrol berpindah ke perintah LOOP di dalam blok yang melingkupinya, sub-blok mulai berjalan kembali, dan transaksi dicoba kembali. Kita mungkin intin menggunakan sebuah FOR atau WHILE loop untuk membatasi jumlah usaha.

DECLARE
  name VARCHAR2(20);
  ans1 VARCHAR2(3);
  ans2 VARCHAR2(3);
  ans3 VARCHAR2(3);
  suffix NUMBER := 1;
BEGIN
  ...
  LOOP -- dapat berupa FOR i IN 1..10 LOOP untuk memperbolehkan sepuluh usaha
    BEGIN -- sub-blok mulai
      SAVEPOINT start_transaction; -- menandai sebuah savepoint
      /* Menghapus baris data dari table hasil survey. */
      DELETE FROM results WHERE answer1 = ’NO’;
      /* Menambahkan sebuah nama dan jawaban responden survey. */
      INSERT INTO results VALUES (name, ans1, ans2, ans3);
      -- menyebabkan DUP_VAL_ON_INDEX jika dua responden memiliki nama yang sama
      COMMIT;
      EXIT;
      EXCEPTION
        WHEN DUP_VAL_ON_INDEX THEN
          ROLLBACK TO start_transaction; -- membatalkan perubahan-perubahan
            suffix := suffix + 1; -- berusaha memperbaiki problem
            name := name || TO_CHAR(suffix);
    END; -- sub-blok selesai
  END LOOP;
END;

7.9.3. Menggunakan Locator Variables untuk Mengidentifikasi Lokasi Exceptions

Menggunakan satu exception handler untuk sebuah rangkaian perintah-perintah dapat menyembunyikan perintah yang menyebabkan error:

BEGIN
  SELECT ...
  SELECT ...
  EXCEPTION
    WHEN NO_DATA_FOUND THEN ... -- Perintah SELECT mana yang menyebabkan error?
END;

 

Secara normal, hal ini bukan masalah. Namun, jika dibutuhkan, kita dapat menggunakan locator variable untuk mengikuti eksekusi perintah, seperti berikut ini:

DECLARE
  stmt INTEGER := 1; -- menunjuk perintah SELECT pertama
BEGIN
  SELECT ...
  stmt := 2; -- menunjuk perintah SELECT kedua
  SELECT ...
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      INSERT INTO errors VALUES ('Error in statement ' || stmt);
END;

Silahkan melanjutkan membaca pembahasan PL/SQL Subprograms

 

 

Pages: 1 2 3 4 5 6 7


Bookmark and Share

 

Buku ini membahas berbagai macam tip dan trik yang sangat berguna bagi Anda pembaca pengguna database Oracle. Pemula, mahasiswa, programmer, maupun database administrator yang mengharapkan solusi cepat dalam menangani permasalahan-permasalahan dalam penggunaan database Oracle dapat membaca buku ini. Anda tidak harus membaca buku ini secara urut karena buku ini di susun berdasarkan topik permasalahan, dan Anda dapat membaca topik-topik yang sesuai dengan permasalahan yang Anda hadapi.
Dapat di beli di toko buku Gramedia, Gunung Agung, Uranus, Karisma, Uranus dsb.

 

Find Related articles