保护 MySQL 中的行不被删除

发布于 2024-12-23 07:54:28 字数 789 浏览 5 评论 0原文

我想保护某些行不被删除,并且我更喜欢使用触发器而不是应用程序的逻辑来执行此操作。我正在使用 MySQL 数据库。

我想出的是这样的:

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 ;

但是当我使用删除时它给了我一个错误:

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.

还有其他方法来做这样的事情吗?

I want to protect some rows from deletion and I prefer to do it using triggers rather than logic of my application. I am using MySQL database.

What I came up with is this:

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 ;

But it gives me an error when I use delete:

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.

Is there another way to do such a thing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

毁梦 2024-12-30 07:54:28

一种解决方案是创建一个带有权限表外键的子表,并添加引用您要阻止删除的各个行的依赖行。

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);

现在您无法从权限中删除 id 为 1234 的行,因为这会违反外键依赖性。

如果您确实想使用触发器来执行此操作,则不必在有人尝试删除行时重新插入行,只需中止删除即可。 MySQL 5.5 具有 SIGNAL 功能来引发 SQLEXCEPTION存储过程或触发器。

如果您使用 MySQL 5.0 或 5.1,则不能使用 SIGNAL,但您可以使用一个技巧,即在触发器中声明一个本地 INT 变量并尝试为其分配一个字符串值。这是数据类型冲突,因此它会引发错误并中止生成触发器的操作。额外聪明的技巧是在您尝试填充到 INT 中的字符串中指定适当的错误消息,因为该字符串将在错误中报告! :-)

One solution would be to create a child table with a foreign key to your permissions table, and add dependent rows referencing the individual rows for which you want to block deletion.

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);

Now you can't delete the row from permissions with id 1234, because it would violate the foreign key dependency.

If you really want to do it with a trigger, instead of re-inserting a row when someone tries to delete it, just abort the delete. MySQL 5.5 has the SIGNAL feature to raise an SQLEXCEPTION in a stored proc or trigger.

If you use MySQL 5.0 or 5.1, you can't use SIGNAL but you can use a trick which is to declare a local INT variable in your trigger and try to assign a string value to it. This is a data type conflict so it throws an error and aborts the operation that spawned the trigger. The extra clever trick is to specify an appropriate error message in the string you try to stuff into the INT, because that string will be reported in the error! :-)

三岁铭 2024-12-30 07:54:28

创建一张新表并创建一个外键。在删除时设置外键 - 限制。

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

注意:这对于 MyISAM、BlackHole 等引擎是不可能完成的。与 InnoDB 及其后代引擎一起使用。

Create one new table and create a foreign key. Set the foreign key on delete - restrict.

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

Note: This is not possible to be done with MyISAM, BlackHole, etc. engine. Use with InnoDB and descendant engines.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文