Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Bekerja dengan Pemicu di Database MySQL - Sebuah Tutorial

Sebuah pemicu adalah perintah SQL yang telah ditentukan sebelumnya yang dijalankan secara otomatis ketika tindakan tertentu terjadi dalam database. Itu dapat diaktifkan sebelum atau sesudah INSERT , UPDATE , atau DELETE acara.

Pemicu terutama digunakan untuk memelihara logika perangkat lunak di server MySQL, dan memiliki beberapa manfaat:

  • Pemicu membantu menjaga operasi global terpusat di satu lokasi.

  • Mereka mengurangi kode sisi klien dan membantu meminimalkan perjalanan bolak-balik yang dilakukan ke server database.

  • Mereka membantu membuat aplikasi lebih skalabel di berbagai platform.

Beberapa kasus penggunaan pemicu yang umum mencakup pencatatan audit, nilai basis data pra-komputasi (misalnya jumlah kumulatif), dan penegakan aturan integritas dan validasi data yang kompleks.

Dalam panduan ini, Anda akan mempelajari:

  • Bagaimana sintaks untuk pemicu disusun.

  • Cara membuat pemicu yang dieksekusi sebelum kejadian database lainnya terjadi.

  • Cara membuat pemicu yang dieksekusi setelah kejadian database lain terjadi.

  • Cara menghapus pemicu.

Sebelum Anda Mulai

  1. Jika Anda belum melakukannya, buat akun Linode dan Compute Instance. Lihat panduan Memulai Linode dan Membuat Instans Komputasi.

  2. Ikuti panduan Menyiapkan dan Mengamankan Instans Komputasi untuk memperbarui sistem Anda. Anda mungkin juga ingin mengatur zona waktu, mengkonfigurasi nama host Anda, membuat akun pengguna terbatas, dan memperkuat akses SSH.

  3. Server dan klien MySQL diinstal pada server Linode. Panduan penginstalan untuk MySQL tersedia untuk distribusi yang berbeda di bagian MySQL kami.

Siapkan Database

Untuk lebih memahami cara kerja pemicu, kami akan membuat database sampel dan menambahkan data sampel ke dalamnya. Nanti, kita akan membuat trigger yang berbeda pada database sebagai bukti latihan konsep.

  1. Pertama, masuk ke Server MySQL Anda:

    mysql -u root -p
    

    Kemudian, masukkan kata sandi root server MySQL Anda dan tekan Enter untuk melanjutkan.

  2. Selanjutnya, Anda akan melihat prompt MySQL yang mirip dengan yang ditunjukkan di bawah ini:

    mysql >
  3. Buat test_database dengan menjalankan perintah di bawah ini:

    CREATE DATABASE test_database;
    

    Keluaran:

    Query OK, 1 row affected (0.02 sec)
  4. Beralih ke database:

    USE test_database;
    

    Keluaran:

    Database changed
  5. Setelah database dipilih, kita akan membuat beberapa tabel yang akan kita gunakan untuk mendemonstrasikan trigger. Kita akan mulai dengan membuat stores meja. Tabel ini akan menyimpan informasi tentang dua toko/kantor sampel tempat bisnis hipotetis kami beroperasi:

    CREATE TABLE stores
    (
    store_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    store_name VARCHAR(50)
    ) ENGINE=InnoDB;
    

    Keluaran:

    Query OK, 0 rows affected (0.07 sec)
  6. Selanjutnya, tambahkan dua record ke stores tabel dengan menjalankan perintah di bawah ini:

    INSERT INTO stores (store_name) VALUES ('Philadelphia');
    INSERT INTO stores (store_name) VALUES ('Galloway');
    

    Setelah setiap perintah, Anda akan mendapatkan output di bawah ini:

    Query OK, 1 row affected (0.08 sec)
    ...
  7. Konfirmasikan catatan dengan menjalankan perintah di bawah ini:

    SELECT * FROM stores;
    

    Keluaran:

    +----------+--------------+
    | store_id | store_name   |
    +----------+--------------+
    |        1 | Philadelphia |
    |        2 | Galloway     |
    +----------+--------------+
    2 rows in set (0.01 sec)
  8. Selanjutnya, buat products meja. Tabel akan berisi berbagai produk yang ditawarkan di toko:

    CREATE TABLE products
    (
    product_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    product_name VARCHAR(40),
    cost_price DOUBLE,
    retail_price DOUBLE,
    availability VARCHAR(5)
    ) ENGINE=InnoDB;
    

    Keluaran:

    Query OK, 0 rows affected (0.13 sec)
    • Setiap produk akan diidentifikasi secara unik dengan product_id .

    • product_name field akan menentukan nama item.

    • cost_price dan retail_price kolom akan menentukan harga beli dan harga jual masing-masing.

    • Sebuah availability kolom akan menentukan ketersediaan produk di toko yang berbeda. Jika produk hanya tersedia di toko lokal kami (Philadelphia), kami akan menandainya dengan LOCAL nilai. Jika tidak, kita akan menggunakan nilai ALL untuk menandakan produk yang tersedia di kedua toko (Philadelphia dan Galloway).

  9. Tambahkan data sampel ke products tabel:

    INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('WIRELESS MOUSE', '18.23', '30.25','ALL');
    
    INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('8 MP CAMERA', '60.40', '85.40','ALL');
    
    INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('SMART WATCH', '189.60', '225.30','LOCAL');
    

    Anda akan mendapatkan output yang ditunjukkan di bawah ini setelah setiap memasukkan perintah:

    Query OK, 1 row affected (0.02 sec)
    ...
  10. Konfirmasikan apakah produk telah dimasukkan dengan menjalankan perintah di bawah ini:

    SELECT * FROM products;
    

    Keluaran:

    +------------+----------------+------------+--------------+--------------+
    | product_id | product_name   | cost_price | retail_price | availability |
    +------------+----------------+------------+--------------+--------------+
    |          1 | WIRELESS MOUSE |      18.23 |        30.25 | ALL          |
    |          2 | 8 MP CAMERA    |       60.4 |         85.4 | ALL          |
    |          3 | SMART WATCH    |      189.6 |        225.3 | LOCAL        |
    +------------+----------------+------------+--------------+--------------+
    3 rows in set (0.00 sec)
  11. Selanjutnya, ketersediaan produk akan dipetakan ke tabel lain bernama products_to_stores . Tabel ini hanya akan mereferensikan product_id dari products tabel dan store_id dari stores tabel tempat item tersedia.

    Buat products_to_stores tabel dengan menjalankan kode di bawah ini:

    CREATE TABLE products_to_stores
    (
    ref_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    product_id BIGINT,
    store_id BIGINT
    ) ENGINE=InnoDB;
    

    Keluaran:

    Query OK, 0 rows affected (0.14 sec)
  12. Selanjutnya, kita akan membuat archived_products meja. Tabel akan menyimpan informasi tentang produk yang dihapus untuk referensi di masa mendatang:

    CREATE TABLE archived_products
    (
    product_id BIGINT PRIMARY KEY ,
    product_name VARCHAR(40),
    cost_price DOUBLE,
    retail_price DOUBLE,
    availability VARCHAR(5)
    ) ENGINE=InnoDB;
    

    Keluaran:

    Query OK, 0 rows affected (0.14 sec)
  13. Terakhir, kita akan membuat products_price_history tabel untuk melacak harga yang berbeda dari setiap produk dari waktu ke waktu:

    CREATE TABLE products_price_history
    (
    product_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    price_date DATETIME,
    retail_price DOUBLE
    ) ENGINE=InnoDB;
    

    Keluaran:

    Query OK, 0 rows affected (0.14 sec)

Setelah struktur database kami siap, sekarang kami dapat melanjutkan dan mempelajari sintaks dasar pemicu database MySQL untuk membuat sampel pertama kami.

Sintaks Pemicu

Seperti yang ditunjukkan sebelumnya, pemicu diaktifkan secara otomatis sebelum atau setelah perintah SQL dijalankan di database. Sintaks dasar untuk membuat pemicu adalah sebagai berikut:

CREATE TRIGGER TRIGGER_NAME

TRIGGER_TIME TRIGGER_EVENT

ON TABLE_NAME FOR EACH ROW

[TRIGGER BODY];
  • TRIGGER_NAME :Setiap pemicu harus memiliki nama unik dan Anda harus mendefinisikannya di sini.

  • TRIGGER_TIME :Baik BEFORE atau AFTER .

  • TRIGGER_EVENT :Anda perlu menentukan kejadian database yang akan memanggil pemicu:INSERT , UPDATE , atau DELETE .

  • TRIGGER BODY :Ini menentukan perintah SQL aktual (atau perintah) yang ingin Anda jalankan oleh pemicu Anda.

Jika badan pemicu memiliki lebih dari satu pernyataan SQL, Anda harus menyertakannya dalam BEGIN...END memblokir. Selain itu, Anda perlu mengubah sementara DELIMITER yang menandakan akhir dari tubuh pemicu ke nilai baru. Ini memastikan bahwa pernyataan di dalam tubuh tidak ditafsirkan secara prematur oleh klien MySQL Anda. Contohnya seperti berikut ini:

DELIMITER &&

CREATE TRIGGER TRIGGER_NAME

TRIGGER_TIME TRIGGER_EVENT

ON TABLE_NAME FOR EACH ROW

BEGIN

[TRIGGER BODY]

END &&

DELIMITER ;
Catatan Baris terakhir dari contoh ini mengubah DELIMITER kembali ke default ; nilai.

Membuat Sebelum Pemicu Peristiwa

Di bagian ini, kita akan melihat berbagai jenis pemicu yang dipicu sebelum operasi database. Ini termasuk BEFORE INSERT , BEFORE UPDATE , dan BEFORE DELETE pemicu.

Membuat Pemicu Sebelum Sisipan

Kami akan membuat BEFORE INSERT pertama kami pemicu. Pemicu akan memastikan bahwa harga eceran suatu produk lebih besar dari harga pokok setiap kali item dimasukkan ke dalam products meja. Jika tidak, pengguna database akan mendapatkan kesalahan.

  1. Saat masih di mysql > prompt, masukkan perintah di bawah ini:

    DELIMITER $$
    
    CREATE TRIGGER price_validator
    
    BEFORE INSERT
    
    ON products FOR EACH ROW
    
    IF NEW.cost_price>=NEW.retail_price
    
    THEN
    
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Retail price must be greater than cost price.';
    
    END IF $$
    
    DELIMITER ;
    
    • Kode di atas mendefinisikan nama pemicu (price_validator ), waktu (BEFORE ), peristiwa (INSERT ), dan tabel (products ) yang akan terpengaruh.

    • Pemicu kami menggunakan NEW kata kunci untuk memeriksa cost_price dan retail_price sebelum record dimasukkan ke products tabel, menggunakan IF...THEN...END IF pernyataan.

    • Jika cost_price lebih besar atau sama dengan retail price , pemicu kami memberi tahu MySQL untuk mengeluarkan pengecualian khusus yang menginstruksikan pengguna untuk memperbaiki kesalahan.

  2. Untuk menguji pemicu di atas, coba masukkan produk yang melanggar aturan validasi:

    INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('GAMING MOUSE PAD', '145.00', '144.00','LOCAL');
    

    Keluaran:

    ERROR 1644 (45000): Retail price must be greater than cost price.

    Perintah insert di atas seharusnya gagal karena retail_price (144.00) tidak lebih besar dari cost_price (145.00).

Membuat Pemicu Sebelum Pembaruan

Selanjutnya, kita akan membuat BEFORE UPDATE pemicu. Pemicu ini akan mencegah pengguna database mengedit nama produk setelah produk dimasukkan ke dalam database. Jika Anda memiliki beberapa pengguna yang bekerja di database, BEFORE UPDATE trigger dapat digunakan untuk membuat nilai hanya-baca, dan ini dapat mencegah pengguna yang jahat atau ceroboh dari memodifikasi catatan yang tidak perlu.

  1. Buat product_name_validator baru pemicu dengan perintah di bawah ini:

    DELIMITER $$
    
    CREATE TRIGGER product_name_validator
    
    BEFORE UPDATE
    
    ON products FOR EACH ROW
    
    IF NEW.product_name<>OLD.product_name
    
    THEN
    
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Product name is read-only and it can not be changed.';
    
    END IF $$
    
    DELIMITER ;
    

    Pemicu ini membandingkan nilai product_name baru (NEW.product_name ) dan nama lama sudah ada di database (OLD.product_name ). Jika ada ketidakcocokan, pengecualian dilemparkan.

  2. Untuk memanggil product_name_validator pemicu, kami dapat mencoba memperbarui nama produk dengan ID 1 :

    UPDATE products SET product_name='WIRELESS BLUETOOTH MOUSE' WHERE product_id='1';
    

    Keluaran:

    ERROR 1644 (45000): Product name is read-only and it can not be changed.

Mendefinisikan Pemicu Sebelum Menghapus

Di bagian ini, Anda akan melihat bagaimana Anda dapat menentukan BEFORE DELETE pemicu untuk mencegah pengguna menghapus catatan tertentu dari tabel.

  1. Untuk membuat prevent_delete pemicu, jalankan perintah di bawah ini:

    DELIMITER $$
    
    CREATE TRIGGER prevent_delete
    
    BEFORE DELETE
    
    ON products FOR EACH ROW
    
    IF OLD.availability='ALL'
    
    THEN
    
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'The product can not be deleted because it is available in ALL stores.';
    
    END IF $$
    
    DELIMITER ;
    

    Pemicu ini akan mencegah produk yang ditandai dengan nilai ALL di kolom ketersediaan agar tidak dihapus.

  2. Selanjutnya, coba hapus produk pertama dari tabel produk dan lihat apakah pemicu akan dipanggil:

    DELETE FROM products WHERE product_id='1';
    

    Keluaran:

    ERROR 1644 (45000): The product can not be deleted because it is available in ALL stores.

Kami telah melihat berbagai pemicu yang dipanggil sebelum operasi database. Selanjutnya, kita akan melihat jenis pemicu lain yang dipicu setelah peristiwa basis data.

Membuat Pemicu Setelah Acara

Di lingkungan produksi, Anda mungkin ingin beberapa pemicu dijalankan secara otomatis setelah kejadian database terjadi (misalnya, menyisipkan rekaman ke dalam tabel yang berbeda). Contoh di bawah ini menunjukkan bagaimana jenis pemicu ini dapat digunakan dalam database sampel kami.

Membuat Pemicu Setelah Sisipan

Contoh ini membuat pemicu bernama product_availability yang menyisipkan catatan pemetaan ke dalam products_to_stores meja. Pemicu ini digunakan untuk menegakkan logika bisnis; khususnya, ini membantu menentukan ketersediaan produk untuk toko yang berbeda.

  1. Jalankan kode di bawah ini untuk membuat product_availability pemicu. Karena kami memiliki beberapa baris kode di badan pemicu, kami akan menggunakan BEGIN...END blok:

    DELIMITER $$
    
    CREATE TRIGGER product_availability
    
    AFTER INSERT
    
    ON products FOR EACH ROW
    
    BEGIN
    
    IF NEW.availability='LOCAL' then
    
    INSERT INTO products_to_stores (product_id, store_id) VALUES (NEW.product_id, '1');
    
    ELSE
    
    INSERT INTO products_to_stores (product_id, store_id) VALUES (NEW.product_id, '1');
    
    INSERT INTO products_to_stores (product_id, store_id) VALUES (NEW.product_id, '2');
    
    END IF;
    
    END $$
    
    DELIMITER ;
    
    • Saat item dimasukkan ke dalam products tabel, pemicu akan memeriksa availability lapangan.

    • Jika ditandai dengan LOCAL nilai, produk hanya akan tersedia di satu toko.

    • Nilai lain apa pun akan menginstruksikan pemicu untuk membuat produk tersedia di dua toko yang kita buat sebelumnya.

  2. Untuk melihat product_availability pemicu beraksi, masukkan dua catatan ke tabel produk:

    INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('BLUETOOTH KEYBOARD', '17.60', '23.30','LOCAL');
    INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('DVB-T2 RECEIVE', '49.80', '53.40','ALL');
    
  3. Kemudian, kueri products_to_stores tabel:

    SELECT * FROM products_to_stores;
    

    Anda akan melihat output yang mirip dengan yang ditunjukkan di bawah ini:

    +--------+------------+----------+
    | ref_id | product_id | store_id |
    +--------+------------+----------+
    |      1 |          4 |        1 |
    |      2 |          5 |        1 |
    |      3 |          5 |        2 |
    +--------+------------+----------+
    3 rows in set (0.00 sec)

Mendefinisikan Pemicu Setelah Pembaruan

Pemicu juga dapat diaktifkan setelah UPDATE peristiwa. Kami akan melihat bagaimana kami dapat memanfaatkan jenis pemicu ini untuk melacak perubahan harga di toko kami dari waktu ke waktu.

  1. Buat product_history_updater memicu dengan menjalankan perintah di bawah ini:

    CREATE TRIGGER product_history_updater
    
    AFTER UPDATE
    
    ON products FOR EACH ROW
    
    INSERT INTO products_price_history (product_id, price_date, retail_price) VALUES (OLD.product_id, NOW(), NEW.retail_price);
    

    Pemicu ini mencatat perubahan pada retail_price produk di products_price_history tabel.

    Catatan Tidak seperti contoh sebelumnya, pemicu ini hanya memiliki satu pernyataan di isi pemicu, jadi kita tidak perlu mengubah DELIMITER .
  2. Kemudian, coba update harga produk pertama dengan menjalankan perintah di bawah ini:

    UPDATE products SET retail_price='36.75' WHERE product_id='1';
    
  3. Selanjutnya, kueri products_price_history tabel untuk melihat apakah perubahan harga telah dicatat:

    SELECT * FROM products_price_history;
    

    Jika pemicu bekerja seperti yang diharapkan, Anda akan mendapatkan output di bawah ini:

    +------------+---------------------+--------------+
    | product_id | price_date          | retail_price |
    +------------+---------------------+--------------+
    |          1 | 2020-01-28 11:46:21 |        36.75 |
    +------------+---------------------+--------------+
    1 row in set (0.00 sec)

Membuat Pemicu Setelah Penghapusan

Dalam beberapa kasus, Anda mungkin ingin mencatat operasi penghapusan setelah tindakan tertentu terjadi di database. Anda dapat mencapai ini dengan menggunakan AFTER DELETE pemicu.

  1. Buat product_archiver baru pemicu dengan perintah di bawah ini:

    CREATE TRIGGER product_archiver
    
    AFTER DELETE
    
    ON products FOR EACH ROW
    
    INSERT INTO archived_products (product_id, product_name, cost_price, retail_price, availability) VALUES (OLD.product_id, OLD.product_name, OLD.cost_price, OLD.retail_price, OLD.availability);
    

    Pemicu ini mengarsipkan produk yang dihapus dalam tabel terpisah bernama archived_products . Saat item dihapus dari products utama tabel, pemicu kami akan secara otomatis mencatatnya ke archived_products tabel untuk referensi di masa mendatang.

  2. Selanjutnya, hapus produk dari products tabel dan lihat apakah pemicu akan dipanggil:

    DELETE FROM products WHERE product_id='3';
    
  3. Sekarang, jika Anda memeriksa archived_products tabel, Anda akan melihat satu record:

    SELECT * FROM archived_products;
    

    Keluaran:

    +------------+--------------+------------+--------------+--------------+
    | product_id | product_name | cost_price | retail_price | availability |
    +------------+--------------+------------+--------------+--------------+
    |          3 | SMART WATCH  |      189.6 |        225.3 | LOCAL        |
    +------------+--------------+------------+--------------+--------------+
    1 row in set (0.00 sec)

Menghapus Pemicu

Anda telah melihat berbagai jenis pemicu dan bagaimana pemicu tersebut dapat digunakan dalam lingkungan produksi. Terkadang, Anda mungkin ingin menghapus pemicu dari database.

Anda dapat menghapus pemicu jika Anda tidak ingin menggunakannya lagi menggunakan sintaks di bawah ini:

DROP TRIGGER IF EXISTS TRIGGER_NAME;
Catatan IF EXISTS kata kunci adalah parameter opsional yang hanya menghapus pemicu jika ada.

Misalnya, untuk menghapus product_archiving pemicu yang kami definisikan di atas, gunakan perintah di bawah ini:

DROP TRIGGER IF EXISTS product_archiver;

Keluaran:

Query OK, 0 rows affected (0.00 sec)
Hati-hati Berhati-hatilah saat menghapus tabel yang terkait dengan pemicu. Setelah tabel dikeluarkan dari database MySQL, pemicu terkait juga akan dihapus secara otomatis.

Informasi Lebih Lanjut

Anda mungkin ingin berkonsultasi dengan sumber daya berikut untuk informasi tambahan tentang topik ini. Meskipun ini disediakan dengan harapan dapat bermanfaat, harap perhatikan bahwa kami tidak dapat menjamin keakuratan atau ketepatan waktu materi yang dihosting secara eksternal.

  • Sintaks dan Contoh Pemicu MySQL

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 5 Alat GUI MySQL Teratas (Gratis &Berbayar)

  2. perlu mengembalikan dua set data dengan dua klausa where yang berbeda

  3. Permintaan MySQL Insert tidak berfungsi dengan klausa WHERE

  4. String MySQL diganti

  5. Cara mengirim email dari MySQL 5.1