mysql - 遍历 MySQL 触发器中的列

标签 mysql loops triggers calculated-columns

是否可以在触发器内循环遍历所有列名?

场景: 记录已修改的表的所有列。 如果某些值未更改,则不要记录这些值。

DROP TRIGGER IF EXISTS t_before_update_test;
DELIMITER $$
CREATE TRIGGER t_before_update_test
BEFORE UPDATE ON test
FOR EACH ROW
BEGIN
    -- Loop here for all columns, not just col1
    IF OLD.col1 <> NEW.col1 THEN
        INSERT INTO change_logs(
            log_on, user_id,
            table_name, colum_name,
            old_data, new_data
        ) VALUES (
            UNIX_TIMESTAMP(NOW()), '0',
            'test', 'col1',
            OLD.col1, NEW.col1
        );
    END IF;
    -- process looping all columns
    -- col1, col2, ... should be dynamic per loop
END $$

这是工作副本示例,我现在需要在其中循环遍历 OLD 或 NEW 中可用的所有列。

最佳答案

我现在没有足够的时间来完成这个,但我认为使用 CONCAT() 来准备一个语句并将其结果用于条件可能会让你做你要。沿着这些线的东西:

DECLARE num_rows INT DEFAULT 0;
DECLARE cols CURSOR FOR SELECT column_name FROM information_schema.columns WHERE table_name = 'table_name' ORDER BY ordinal_position;

OPEN cols; 
SELECT FOUND_ROWS() INTO num_rows; 
SET @i = 1;

cols_loop: LOOP

    IF @i > num_rows THEN
        CLOSE cols;
        LEAVE cols_loop;
    END IF;

    FETCH cols INTO col;

    SET @do_stuff = 0;
    SET @s = CONCAT('SELECT IF(NEW.', col, ' <> OLD.', col, ', 1, 0) INTO @do_stuff');

    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

    IF @do_stuff = 1 THEN
        SET @s2 = CONCAT('INSERT INTO change_logs(log_on, user_id, table_name, colum_name, old_data, new_data ) 
                          VALUES (UNIX_TIMESTAMP(NOW()), ''0'', ''test'', ''', col,''', OLD.', col, ', NEW.', col, ');');

        PREPARE stmt2 FROM @s2;
        EXECUTE stmt2;
        DEALLOCATE PREPARE stmt2;
    END IF;

    SET @i = @i + 1;  
END LOOP cols_loop;

CLOSE cols; 

关于mysql - 遍历 MySQL 触发器中的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24228255/

相关文章:

即使有尝试,Python 循环也会重新启动 : except:

c# - 读取麦克风分贝和音调/频率

SQL代替触发器和更新

mysql - FROM_UNIXTIME 和性能

mysql - 数据库设计 - 哪个最适合这个?

C# MySQL 作为多行字符串

javascript - 从所有节点列表元素中删除样式并仅添加到单击的元素 Vanilla JS

ruby 循环。散列成字符串

MySQL 跨表约束

php - fatal error : Object of class mysqli could not be converted to string