Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Kích hoạt MySQL Before Delete để tránh xóa nhiều hàng

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ì ; ) trong DROP TRIGGER IF EXISTS .. tuyên bố.
  • Row_Count() sẽ có giá trị 0 trong Before 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   |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tinh chỉnh hiệu suất InnoDB

  2. viết lại mod, slugs tiêu đề và htaccess

  3. Thiếu kết nối cơ sở dữ liệu Mysql và thiếu mysql.sock

  4. Double JOIN với cùng một bảng hai lần

  5. Chỉ truy xuất một số hàng cố định trong MySQL