2011-12-30 23 views
12

Tôi muốn bảo vệ một số hàng khỏi việc xóa và tôi muốn thực hiện việc này bằng cách sử dụng trình kích hoạt thay vì logic của ứng dụng của tôi. Tôi đang sử dụng cơ sở dữ liệu MySQL.Bảo vệ hàng khỏi việc xóa trong MySQL

Những gì tôi đã đưa ra là thế này:

DELIMITER $$ 

DROP TRIGGER `preserve_permissions`$$ 

USE `systemzarzadzaniareporterami`$$ 

CREATE TRIGGER `preserve_permissions` 
AFTER DELETE ON `permissions` 
FOR EACH ROW 
BEGIN 
IF old.`userLevel` = 0 AND old.`permissionCode` = 164 THEN 
    INSERT INTO `permissions` SET `userLevel`=0, `permissionCode`=164; 
END IF; 
END$$ 

DELIMITER ; 

Nhưng nó mang lại cho tôi một lỗi khi tôi sử dụng xóa:

DELETE FROM `systemzarzadzaniareporterami`.`permissions` 
WHERE `userLevel` = 0 AND `permissionCode` = 164; 

Error Code: 1442. Can't update table 'permissions' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. 

Có một cách khác để làm một điều như vậy?

Trả lời

13

Một giải pháp là tạo bảng con bằng khóa ngoài cho bảng quyền của bạn và thêm hàng phụ thuộc tham chiếu đến các hàng riêng lẻ mà bạn muốn chặn xóa.

CREATE TABLE preserve_permissions (
    permission_id INT PRIMARY KEY, 
    FOREIGN KEY (permission_id) REFERENCES permissions (permission_id) 
); 

INSERT INTO perserve_permissions (permission_id) VALUES (1234); 

Bây giờ bạn không thể xóa hàng khỏi các quyền với id 1234, vì nó sẽ vi phạm sự phụ thuộc của khóa ngoại.

Nếu bạn thực sự muốn làm điều đó bằng trình kích hoạt, thay vì chèn lại hàng khi ai đó cố gắng xóa nó, chỉ cần hủy xóa. MySQL 5.5 có tính năng SIGNAL để tăng SQLEXCEPTION trong một proc hoặc trigger được lưu trữ.

Nếu bạn sử dụng MySQL 5.0 hoặc 5.1, bạn không thể sử dụng SIGNAL nhưng bạn có thể sử dụng mẹo để khai báo biến INT cục bộ trong trình kích hoạt và cố gán giá trị chuỗi cho nó. Đây là một xung đột kiểu dữ liệu, do đó nó ném một lỗi và hủy bỏ hoạt động sinh ra trình kích hoạt. Thủ thuật thông minh hơn là chỉ định một thông báo lỗi thích hợp trong chuỗi bạn cố gắng nhồi nhét vào INT, bởi vì chuỗi đó sẽ được báo cáo trong lỗi! :-)

10

Tạo một bảng mới và tạo khóa ngoại. Đặt khóa ngoại trên xóa - giới hạn.

CONSTRAINT FOREIGN KEY fk_restriction (restriction_col) 
table_to_restrict (restricted_id) ON DELETE RESTRICT ON UPDATE CASCADE 

Lưu ý: Điều này không thể thực hiện được với động cơ MyISAM, BlackHole, v.v. Sử dụng với InnoDB và các công cụ hậu duệ.

Các vấn đề liên quan