Mysql 创建触发器以更新排序/顺序列

Mysql 创建触发器以更新排序/顺序列,mysql,function,triggers,insert,Mysql,Function,Triggers,Insert,我创建这个触发器是为了更新seq列。我必须跟踪表中某些项目的顺序,但前提是负债类别id=1,2。因此,我的订购很棘手,因为我不需要跟踪任何负债类别id=3的项目 在我的触发器中,我查询查找最后输入的序号(使用max(seq)),然后返回并用seq+1更新新条目 DELIMITER $$ USE `analysisdb`$$ DROP TRIGGER /*!50032 IF EXISTS */ `trigger_liability_detail_after_insert`$$ CREATE

我创建这个触发器是为了更新seq列。我必须跟踪表中某些项目的顺序,但前提是负债类别id=1,2。因此,我的订购很棘手,因为我不需要跟踪任何负债类别id=3的项目

在我的触发器中,我查询查找最后输入的序号(使用max(seq)),然后返回并用seq+1更新新条目

DELIMITER $$

USE `analysisdb`$$

DROP TRIGGER /*!50032 IF EXISTS */ `trigger_liability_detail_after_insert`$$

CREATE
/*!50017 DEFINER = 'admin'@'%' */
TRIGGER `trigger_liability_detail_after_insert` AFTER INSERT ON `liability_detail` 
    FOR EACH ROW BEGIN
    DECLARE SortOrder INT;
    IF NEW.liability_category_id = 1 OR NEW.liability_category_id = 2 THEN

    SET SortOrder = (SELECT MAX(seq) FROM liability_detail WHERE analysis_id = new.analysis_id AND liability_category_id IN (1, 2));
    UPDATE liability_detail SET seq = (SortOrder + 1) WHERE id = NEW.id;
    END IF;
    END;
$$

DELIMITER ;
但是,当输入一个新项时,我会遇到以下错误:无法更新存储函数/触发器中的表'liability\u detail',因为调用此存储函数/触发器的语句已经使用了它。


有没有更好的方法来控制这些物品的订购?我最初的想法是简单地设置第一个seq=1,然后seq=2,等等。不过,对于每个新的分析id,顺序都会重置。

我认为解决方法是将此设置为before触发器,并在插入之前更新正在插入的记录本身

所以


这是一个快速的复制/粘贴,但它应该是类似于这些内容的。

这将是一个棘手的问题

简单的答案是,如果可以在每行插入之前将其更改为
触发器, 然后你可以:

SET NEW.seq = (SortOrder + 1);
在将行插入表之前设置行上的值。但不能在每行触发器的后插入中执行此操作

使用触发器存在一些性能和并发性问题。(您不能保证在运行并发插入时不会为
seq
列生成“重复”值;但这可能不是您的问题。)

我更喜欢对整个表使用简单的
AUTO_INCREMENT
列的方法

其中的值对于所有行都是“有序”的,因此

... WHERE liability_category_id = 1 ORDER BY seq 
将按插入行的顺序返回行。对于给定的
责任类\u id
,序列号中会有“间隙”,但插入的序列(顺序)将被保留

(注意:MyISAM有一个漂亮的自动递增列功能,让我们分别为索引中前导列的不同值“递增”。但这只在MyISAM引擎中起作用,在InnoDB中不起作用。)

除了AutoYLoad列之外,我还将考虑<代码>时间戳默认CurrnTyTimePopys/Cuff>列来记录插入行的日期/时间。

... WHERE liability_category_id = 1 ORDER BY timestamp_default_current ASC

这两种方法都是简单的列定义,不需要编写或维护任何程序代码。

以这种方式更新列可能会导致多行具有相同的seq值,因为在插入过程中可以读取max值,但在另一次插入过程中再次读取max值之前不会进行更新。您应该使用“自动增量”来处理此问题。
... WHERE liability_category_id = 1 ORDER BY timestamp_default_current ASC