创建一个触发更新排序/顺序列(Creating a trigger to update a sort

2019-10-17 01:09发布

我创建了这个触发更新以次列。 我跟踪表中的某些项目的顺序的,但前提是liability_category_id = 1,2。 所以,因为有liability_category_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_detail”。

有没有更好的办法来控制这些项目的排序? 我最初的想法是简单地设置第一SEQ = 1,则SEQ = 2等的顺序被重置为每个新analysis_id虽然。

Answer 1:

我认为,解决办法是触发之前,使这个和更新记录作为嵌入自身插入之前。

所以

CREATE
/*!50017 DEFINER = 'admin'@'%' */
TRIGGER `trigger_liability_detail_after_insert` BEFORE 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 NEW.seq = 1 + IFNULL((SELECT MAX(seq) FROM liability_detail WHERE analysis_id = new.analysis_id AND liability_category_id IN (1, 2)), 0);
    END IF;
    END;
$$

这是一个快速的复制/粘贴,但它应该是类似的规定。



Answer 2:

这将是棘手的处理。

最简单的答案是,如果这可以被更改为BEFORE INSERT FOR EACH ROW触发器,那么你可以:

SET NEW.seq = (SortOrder + 1);

之前,它被插入到表上设置该行的值。 但是,你不能这样做,在INSERT FOR EACH ROW AFTER触发器。

有使用触发一些性能和并发性的担忧。 (你没有,你不会产生“重复”的价值任何保证seq当并发插入正在运行的列;但可能不适合你是一个显示塞问题。)

我宁愿用一个简单的方法AUTO_INCREMENT列整个表。

从该值将是“按顺序”的所有行,所以像查询

... WHERE liability_category_id = 1 ORDER BY seq 

将“提交订单”的行插入返回行。 会有在对于给定的序列号“间隙” liability_category_id ,但插入物的序列(顺序)将被保留。

(注意:MyISAM数据有一个AUTO_INCREMENT列的漂亮的功能,让我们为“增量”分别在索引中的前导列的不同值,但只工作在MyISAM引擎,它不能在InnoDB的工作)

除了一个AUTO_INCREMENT列,我也会考虑一个TIMESTAMP DEFAULT CURRENT_TIMESTAMP列插入的行时录制日期/时间。

... WHERE liability_category_id = 1 ORDER BY timestamp_default_current ASC

这两个方法都是简单的列定义,并且不需要任何程序代码被写入或维护。



文章来源: Creating a trigger to update a sort/order column