MySQL:在删除触发器中引用当前行
我在MySQL中删除后引用MySQL:在删除触发器中引用当前行,mysql,triggers,sql-delete,Mysql,Triggers,Sql Delete,我在MySQL中删除后引用触发器中的当前行时遇到问题。假设我有以下书籍表格: +----+------+----------+ | id | name | ordering | +----+------+----------+ | 1 | It | 3 | | 2 | Cujo | 1 | | 3 | Rage | 2 | +----+------+----------+ 我想创建一个触发器,它将递减所有排序值大于已删除行中排序值的行。例如,
触发器中的当前行时遇到问题。假设我有以下书籍
表格:
+----+------+----------+
| id | name | ordering |
+----+------+----------+
| 1 | It | 3 |
| 2 | Cujo | 1 |
| 3 | Rage | 2 |
+----+------+----------+
我想创建一个触发器,它将递减所有排序
值大于已删除行中排序
值的行。例如,如果我从id=2的书籍中删除,我希望生成的表如下所示:
+----+------+----------+
| id | name | ordering |
+----+------+----------+
| 1 | It | 2 |
| 3 | Rage | 1 |
+----+------+----------+
我试过:
DROP TRIGGER IF EXISTS reorder_books_on_delete;
DELIMITER $$
CREATE TRIGGER reorder_books_on_delete
AFTER DELETE ON books
FOR EACH ROW
BEGIN
IF ordering > OLD.ordering
THEN
UPDATE books SET ordering = ordering - 1
WHERE id = id;
END IF;
END$$
DELIMITER ;
但在表上执行DELETE
时,这会导致错误:
错误1054(42S22):“where子句”中的未知列“ordering”
这引用了if
语句,那么如何在DELETE
触发器上引用中的当前行呢?这个专栏确实存在 它失败的原因是因为没有当前
行,因此,排序
列不存在,应该在WHERE
子句中使用它,如下所示:
DROP TRIGGER IF EXISTS reorder_books_on_delete;
DELIMITER $$
CREATE TRIGGER reorder_books_on_delete
AFTER DELETE ON books
FOR EACH ROW
BEGIN
UPDATE books SET ordering = ordering - 1
WHERE ordering > OLD.ordering;
END$$
DELIMITER ;
但是,根据MySQL,您不能这样做,它将返回以下错误:
SQL错误(1442):无法更新存储中的表“books”
函数/触发器,因为调用
此存储函数/触发器
因此,您必须在单个事务中的DELETE
查询之后运行另一个UPDATE
查询才能实现此功能。它失败的原因是没有当前的
行,因此,ordering
列不存在,应该在WHERE
子句中使用它,如下所示:
DROP TRIGGER IF EXISTS reorder_books_on_delete;
DELIMITER $$
CREATE TRIGGER reorder_books_on_delete
AFTER DELETE ON books
FOR EACH ROW
BEGIN
UPDATE books SET ordering = ordering - 1
WHERE ordering > OLD.ordering;
END$$
DELIMITER ;
但是,根据MySQL,您不能这样做,它将返回以下错误:
SQL错误(1442):无法更新存储中的表“books”
函数/触发器,因为调用
此存储函数/触发器
因此,您必须在单个事务中的删除查询之后运行另一个更新
查询来实现此功能。正如Darshan所说,您不能使用触发器来完成此操作。。。。但是,程序可以为你创造条件
DROP PROCEDURE IF EXISTS delete_book;
DELIMITER //
CREATE PROCEDURE delete_book(IN pId INT)
BEGIN
set @a = (
SELECT ordering
FROM books
WHERE id = pId
);
UPDATE books SET ordering = ordering - 1
WHERE ordering > @a;
delete from books
WHERE id = pId;
END
//
DELIMITER ;
您只需要调用DELETE\u book(4),而不是从id=4的书籍中删除代码>正如Darshan所说,你不能用触发器来做这件事。。。。但是,程序可以为你创造条件
DROP PROCEDURE IF EXISTS delete_book;
DELIMITER //
CREATE PROCEDURE delete_book(IN pId INT)
BEGIN
set @a = (
SELECT ordering
FROM books
WHERE id = pId
);
UPDATE books SET ordering = ordering - 1
WHERE ordering > @a;
delete from books
WHERE id = pId;
END
//
DELIMITER ;
您只需要调用DELETE\u book(4),而不是从id=4的书籍中删除代码>