Pertama, menghilangkan beberapa kesalahan sintaksis, dari upaya awal Anda:
- Alih-alih
FOR EACH STATEMENT
, seharusnyaFOR EACH ROW
. - Karena Anda telah mendefinisikan Pembatas menjadi
//
; anda perlu menggunakan//
(bukan;
) diDROP TRIGGER IF EXISTS ..
pernyataan. Row_Count()
akan memiliki nilai 0 dalamBefore Delete Trigger
, karena belum ada baris yang diperbarui. Jadi pendekatan ini tidak akan berhasil.
Sekarang, triknya di sini adalah menggunakan Dapat diakses tingkat sesi (dan Persisten) variabel yang ditentukan pengguna
. Kita dapat mendefinisikan sebuah variabel, misalkan @rows_being_deleted
, dan nanti periksa apakah sudah ditentukan atau belum.
For Each Row
menjalankan kumpulan pernyataan yang sama untuk setiap baris yang dihapus . Jadi, kita tinggal mengecek apakah variabel session sudah ada atau belum. Jika tidak, kita bisa mendefinisikannya. Jadi pada dasarnya, untuk baris pertama (yang dihapus), itu akan ditentukan, yang akan bertahan selama sesi itu ada.
Sekarang jika ada lebih banyak baris yang akan dihapus, Pemicu akan menjalankan kumpulan pernyataan yang sama untuk baris yang tersisa. Di baris kedua, variabel yang telah didefinisikan sebelumnya akan ditemukan sekarang, dan kita cukup melempar pengecualian sekarang.
Catatan bahwa ada kemungkinan bahwa dalam sesi yang sama, beberapa pernyataan penghapusan dapat dipicu. Jadi sebelum melempar pengecualian, kita perlu mengatur @rows_being_deleted
nilai kembali ke null
.
Berikut ini akan berfungsi:
DELIMITER //
DROP TRIGGER IF EXISTS prevent_multiple_deletion //
CREATE TRIGGER prevent_multiple_deletion
BEFORE DELETE ON `test`
FOR EACH ROW
BEGIN
-- check if the variable is already defined or not
IF( @rows_being_deleted IS NULL ) THEN
SET @rows_being_deleted = 1; -- set its value
ELSE -- it already exists and we are in next "row"
-- just for testing to check the row count
-- SET @rows_being_deleted = @rows_being_deleted + 1;
-- We have to reset it to null, as within same session
-- another delete statement may be triggered.
SET @rows_being_deleted = NULL;
-- throw exception
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Cannot delete more than one order per time!';
END IF;
END //
DELIMITER ;
Demo Biola DB 1 :Mencoba menghapus lebih dari satu baris.
DELETE FROM `test` WHERE `id`< 5;
Hasil:
Demo Biola DB 2 :Mencoba menghapus hanya satu baris
Kueri #1
DELETE FROM `test` WHERE `id` = 1;
Kueri #2
SELECT * FROM `test`;
| id | a | b |
| --- | --- | --- |
| 2 | 3 | 4 |