Thứ nhất, chúng tôi gặp phải (các) lỗi cú pháp từ lần thử ban đầu của bạn:
- Thay vì
FOR EACH STATEMENT
, nó phải làFOR EACH ROW
. - Vì bạn đã xác định Dấu phân cách thành
//
; bạn cần sử dụng//
(thay vì;
) trongDROP TRIGGER IF EXISTS ..
tuyên bố. -
Row_Count()
sẽ có giá trị 0 trongBefore Delete Trigger
, vì chưa có hàng nào được cập nhật. Vì vậy, cách làm này sẽ không hiệu quả.
Bây giờ, mẹo ở đây là sử dụng Cấp độ phiên có thể truy cập (và liên tục) biến do người dùng xác định
. Chúng ta có thể xác định một biến, giả sử @rows_being_deleted
và sau đó kiểm tra xem nó đã được xác định hay chưa.
For Each Row
chạy cùng một tập hợp các câu lệnh cho mọi hàng đang bị xóa . Vì vậy, chúng tôi sẽ chỉ kiểm tra xem biến phiên đã tồn tại hay chưa. Nếu không, chúng ta có thể xác định nó. Vì vậy, về cơ bản, đối với hàng đầu tiên (đang bị xóa), nó sẽ được xác định, sẽ tồn tại miễn là phiên còn đó.
Bây giờ nếu có nhiều hàng bị xóa, Trigger sẽ chạy cùng một tập hợp các câu lệnh cho các hàng còn lại. Trong hàng thứ hai, biến được xác định trước đó sẽ được tìm thấy ngay bây giờ và chúng ta có thể chỉ cần ném một ngoại lệ ngay bây giờ.
Lưu ý rằng có khả năng trong cùng một phiên, nhiều câu lệnh xóa có thể được kích hoạt. Vì vậy, trước khi ném ngoại lệ, chúng ta cần đặt @rows_being_deleted
giá trị trở lại null
.
Sau đây sẽ hoạt động:
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 ;
DB Fiddle Demo 1 :Đang cố gắng xóa nhiều hơn hàng.
DELETE FROM `test` WHERE `id`< 5;
Kết quả:
DB Fiddle Demo 2 :Đang cố gắng xóa chỉ một hàng
Truy vấn số 1
DELETE FROM `test` WHERE `id` = 1;
Truy vấn số 2
SELECT * FROM `test`;
| id | a | b |
| --- | --- | --- |
| 2 | 3 | 4 |