Mysql触发器优化。多个表列 IF (OLD.data <> NEW.data)

标签 mysql optimization triggers

这里我有一个正在运行的 MySQL 触发器:

DROP TRIGGER IF EXISTS trg_after_update_tbl1;
DELIMITER //
CREATE TRIGGER trg_after_update_tbl1
    AFTER UPDATE ON db1.tbl1 FOR EACH ROW
    BEGIN
    DECLARE strOld VARCHAR(255);
    DECLARE strNew VARCHAR(255);
    SET strOld = '';
    SET strNew = '';

    IF (NEW.colA <> OLD.colA) THEN 
        SET strOld = CONCAT(strOld, 'colA: ',OLD.colA,'; ');
        SET strNew = CONCAT(strNew, 'colA: ',NEW.colA,'; ');
    END IF;
    IF (NEW.colB <> OLD.colB) THEN 
        SET strOld = CONCAT(strOld, 'colB: ',OLD.colB,'; ');
        SET strNew = CONCAT(strNew, 'colB: ',NEW.colB,'; ');
    END IF;
    IF (NEW.colC <> OLD.colC) THEN 
        SET strOld = CONCAT(strOld, 'colC: ',OLD.colC,'; ');
        SET strNew = CONCAT(strNew, 'colC: ',NEW.colC,'; ');
    END IF;
    -- AND SO MANY COLUMN CLAUSES ON....

    INSERT INTO db1.changes (user, tableName, oldData, newData, date)
    VALUES (
            user(), 
            'tableA', 
            strOld,
            strNew,
            now()
        );
    END//
DELIMITER ;

是否可以将表列名称分配给列表、数组或类似内容中的变量(比如说 X),对其进行迭代并仅使用一个 IF 子句?就像这样(伪代码):

BEGIN LOOP
        IF (NEW.X <> OLD.X) THEN 
            SET strOld = CONCAT(strOld, X, ': ',OLD.X,'; ');
            SET strNew = CONCAT(strNew, X, ': ',NEW.X,'; ');
        END IF;
END LOOP

最佳答案

无论使用哪种 DBMS,您所建议的通常称为动态 SQL,这意味着您正在执行的语句首先需要编译然后执行。

虽然您可以减少代码行数,但也会对性能产生(负面)影响。

正如我常说的,你编写代码一次,但你会多次阅读并运行它。其寓意是:在需要时,花费一些额外的努力来使您的代码可读且高效。

无论如何,MySQL提供Prepared Statements这是它的动态 SQL 版本。

我上面写的有一个异常(exception):当您的两个表包含已知数量的列且全部类型相同时。在这种情况下,您可以将两条记录的内容选择到两个数组中,然后循环遍历数组(但这只是最后一刻的想法)。

关于Mysql触发器优化。多个表列 IF (OLD.data <> NEW.data),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38118196/

相关文章:

mysql - 触发: Referencing updated attribute

MySQL:解决我的 MySQL 光标错误:1064

php - 使用数据库中已有的值更新数据库的值

php - Affected_rows 返回负数 -1 但插入

c - 优化 C 循环以获得数组的对角线

sql - 在 SQL Server 中创建触发器

mysql - 使用 Entity Framework 从数据库中获取标识列中最后一个自动插入的 ID

mysql - Python3 SQL 插入问题

java - 我正在尝试填充图表,存储探索的节点的最优化方法是什么?

java - 计算两点之间地理距离的更快方法