MySQL:在删除触发器中引用当前行

MySQL:在删除触发器中引用当前行,mysql,triggers,sql-delete,Mysql,Triggers,Sql Delete,我在MySQL中删除后引用触发器中的当前行时遇到问题。假设我有以下书籍表格: +----+------+----------+ | id | name | ordering | +----+------+----------+ | 1 | It | 3 | | 2 | Cujo | 1 | | 3 | Rage | 2 | +----+------+----------+ 我想创建一个触发器,它将递减所有排序值大于已删除行中排序值的行。例如,

我在MySQL中删除后引用
触发器中的当前行时遇到问题。假设我有以下
书籍
表格:

+----+------+----------+
| 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的书籍中删除