Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Perbarui Pemicu PL/SQL Oracle

Coba pemicu majemuk:

CREATE OR REPLACE TRIGGER compound_trigger_name
FOR  INSERT OR UPDATE OF salary ON treballa
COMPOUND TRIGGER

  TYPE Departments_t   IS TABLE OF treballa.department%TYPE INDEX BY varchar2(100);
  Departments          Departments_t;

     BEFORE EACH ROW IS
     BEGIN
        -- collect updated or inserted departments 
        Departments( :new.department ) := :new.department;
     END BEFORE EACH ROW;

     AFTER STATEMENT IS
        sum_sal NUMBER;
     BEGIN
      -- for each updated department check the restriction
      FOR dept IN Departments.FIRST .. Departments.LAST
      LOOP
         SELECT sum(salary) INTO sum_sal FROM treballa WHERE department = dept;
         IF sum_sal > 1000 THEN
            raise_application_error(-20123, 'The total salary for department '||dept||' cannot exceed 1000');
         END IF;
      END LOOP;
     END AFTER STATEMENT;

END compound_trigger_name;
/

========EDIT - beberapa pertanyaan dan jawaban ===========

T:Mengapa terjadi kesalahan tabel mutasi ?
J:Ini dijelaskan dalam dokumentasi:
http://docs.Oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#g1699708

T:bagaimana cara menghindari kesalahan mutasi tabel ?
J:Dokumentasi merekomendasikan penggunaan pemicu coumpound, lihat ini:http://docs.Oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#CHDFEBFJ

T:Apa yang dimaksud dengan pemicu majemuk dan bagaimana cara kerjanya ?
J:Ini adalah topik besar, silakan lihat dokumentasi di sini:http://docs.Oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#CIHEFGFD

Singkatnya:ini adalah jenis pemicu khusus yang memungkinkan untuk menggabungkan empat jenis pemicu terpisah:BEFORE statement , BEFORE-for each row , AFTER for each row dan AFTER statament menjadi satu deklarasi. Itu memudahkan untuk mengimplementasikan beberapa skenario di mana ada kebutuhan untuk melewatkan beberapa data dari satu pemicu ke pemicu lainnya. Silakan pelajari tautan di atas untuk detail lebih lanjut.

T:Tapi apa sebenarnya "Departments( :new.department ) := :new.department; ?
A:Deklarasi ini menyimpan nomor departemen ke dalam array asosiatif.

Array ini dideklarasikan di bagian deklaratif dari pemicu gabungan:

  TYPE Departments_t   IS TABLE OF treballa.department%TYPE INDEX BY varchar2(100);
  Departments          Departments_t;

Dokumentasi yang terkait dengan pemicu senyawa mengatakan bahwa:http ://docs.Oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#CIHJBEFE

Di atas berarti Departments variabel diinisialisasi hanya sekali pada awal seluruh pemrosesan, tepat setelah pemicu diaktifkan. "Durasi pernyataan pengaktifan" berarti variabel ini dimusnahkan setelah pemicu selesai.

Pernyataan ini:Departments( :new.department ) := :new.department; menyimpan nomor departemen dalam array asosiatif. Itu ada di BEFORE EACH ROW bagian, kemudian dieksekusi untuk setiap baris yang diperbarui (atau disisipkan) oleh pernyataan update/insert.

:new dan :old adalah pseudorecords, lebih banyak tentang mereka dapat Anda temukan di sini: http://docs.Oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#LNPLS99955
Singkatnya::new.department mengambil nilai baru department kolom- untuk baris yang saat ini diperbarui (nilai yang diperbarui - SETELAH pembaruan), sedangkan :old.department memberikan nilai lama dari kolom ini (SEBELUM update).

Koleksi ini kemudian digunakan dalam AFTER STATEMENT , ketika pemicu memilih semua departemen yang diperbarui (dalam FOR-LOOP), untuk setiap departemen akan mengaktifkan SELECT SUM(salary) ... dan kemudian memeriksa apakah jumlah ini kurang dari 1000

Pertimbangkan pembaruan sederhana:UPDATE treballa SET salary = salary + 10 . Ini adalah pernyataan pembaruan tunggal, tetapi mengubah banyak baris sekaligus. Urutan eksekusi pemicu kami adalah sebagai berikut:

  1. Pernyataan pembaruan dipecat:UPDATE treballa SET salary = salary + 10
  2. Bagian deklaratif pemicu dijalankan, yaitu:Departments variabel diinisialisasi
  3. BEFORE EACH ROW bagian dijalankan, secara terpisah untuk setiap baris yang diperbarui - sebanyak baris yang akan diperbarui. Di tempat ini kami mengumpulkan semua departemen dari baris yang diubah.
  4. AFTER STATEMENT bagian dijalankan. Pada titik ini tabel sudah diperbarui - semua baris sudah memiliki gaji baru yang diperbarui. Kami mengulang departemen yang disimpan di Departments dan untuk masing-masing departemen kami memeriksa apakah jumlah gaji kurang atau sama dengan 1000. Jika jumlah ini> 1000 untuk salah satu departemen ini, maka kesalahan akan terjadi, dan seluruh pembaruan dibatalkan dan dibatalkan. Jika tidak, pemicunya selesai, dan pembaruan selesai (tetapi Anda tetap harus melakukan perubahan ini).

T:Apa yang dimaksud dengan array asosiatif, dan mengapa hanya jenis koleksi ini yang digunakan, bukan koleksi lain (varray atau tabel bersarang)?
J:Koleksi PL/SQL adalah topik besar. Ikuti tautan ini untuk mempelajarinya:http:// docs.Oracle.com/cd/E11882_01/appdev.112/e25519/composites.htm#LNPLS005

Singkatnya - Array asosiatif (atau tabel indeks-oleh) seperti peta di java (hashmap, treemap dll) - itu adalah satu set pasangan kunci-nilai, dan setiap kunci adalah unik . Anda dapat memasukkan kunci yang sama berkali-kali ke larik ini (dengan nilai yang berbeda), tetapi kunci ini hanya akan disimpan sekali - kunci ini unik.
Saya telah menggunakannya untuk mendapatkan kumpulan departemen yang unik.
Pertimbangkan kembali contoh update kami:UPDATE treballa SET salary = salary + 10 - perintah ini menyentuh ratusan baris yang memiliki departemen yang sama. Saya tidak ingin koleksi dengan departemen yang sama diduplikasi 100 kali, saya memerlukan kumpulan departemen yang unik, dan saya ingin menjalankan kueri kami SELECT sum()... hanya sekali untuk setiap departemen, bukan 100 kali. Dengan bantuan array sssociative, ini dilakukan secara otomatis - saya mendapatkan set departemen yang unik.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Konversi Oracle varchar2 ke nvarchar2

  2. EM 12c Menyesuaikan Nilai Ambang Batas

  3. Oracle PLSQL memotong datetime menjadi 15 menit blok

  4. 11 Cara Menemukan Baris Duplikat yang memiliki Kunci Utama di Oracle

  5. Rollback tidak berfungsi di Oracle menggunakan liquibase