gpt4 book ai didi

mysql - 使用 MySQL,如何迭代更新触发器中的字段以比较更改日志的新旧值?

转载 作者:行者123 更新时间:2023-11-29 15:26:23 25 4
gpt4 key购买 nike

当日志记录打开时,我正在尝试使用 MySQL 中的触发器来更新包含表更改的日志表。

UPDATE触发器需要迭代表的所有字段,比较数据变化(OLD.fieldname <> NEW.fieldname),然后将字段名和数据写入日志表。

我编写的代码必须显式命名每个字段。有些表有很多字段,我不喜欢手动输入所有字段名称。

有没有办法以编程方式迭代表的字段,以便我可以创建要调用的存储过程?

我的代码:

CREATE DEFINER=`root`@`localhost` TRIGGER `trgUserUpd` AFTER UPDATE ON `user`
FOR EACH ROW BEGIN
DECLARE rChanges TEXT DEFAULT '';

IF BINARY(OLD.userName) <> BINARY(NEW.userName) THEN
SET rChanges := CONCAT('userName: ', OLD.userName, ' => ', NEW.userName);
END IF;

IF BINARY(OLD.fullName) <> BINARY(NEW.fullName) THEN
IF rChanges <> '' THEN
SET rChanges := CONCAT(rChanges, '
');
END IF;
SET rChanges := CONCAT(rChanges, 'fullName: ', OLD.fullName, ' => ', NEW.fullName);
END IF;

IF BINARY(OLD.initials) <> BINARY(NEW.initials) THEN
IF rChanges <> '' THEN
SET rChanges := CONCAT(rChanges, '
');
END IF;
SET rChanges := CONCAT(rChanges, 'initials: ', OLD.initials, ' => ', NEW.initials);
END IF;

IF BINARY(OLD.password) <> BINARY(NEW.password) THEN
IF rChanges <> '' THEN
SET rChanges := CONCAT(rChanges, '
');
END IF;
SET rChanges := CONCAT(rChanges, 'password changed');
END IF;

IF BINARY(OLD.salt) <> BINARY(NEW.salt) THEN
IF rChanges <> '' THEN
SET rChanges := CONCAT(rChanges, '
');
END IF;
SET rChanges := CONCAT(rChanges, 'salt: ', OLD.salt, ' => ', NEW.salt);
END IF;

IF BINARY(OLD.administrator) <> BINARY(NEW.administrator) THEN
IF rChanges <> '' THEN
SET rChanges := CONCAT(rChanges, '
');
END IF;
SET rChanges := CONCAT(rChanges, 'administrator: ', OLD.administrator, ' => ', NEW.administrator);
END IF;

IF BINARY(OLD.active) <> BINARY(NEW.active) THEN
IF rChanges <> '' THEN
SET rChanges := CONCAT(rChanges, '
');
END IF;
SET rChanges := CONCAT(rChanges, 'active: ', OLD.active, ' => ', NEW.active);
END IF;

CALL ChangeNotify('user', OLD.id, rChanges, 'update');
END;

似乎准备好的语句也不起作用。我刚刚尝试过:

BEGIN
DECLARE rChanges TEXT DEFAULT '';
DECLARE eof INT DEFAULT FALSE;
DECLARE field CHAR(50) DEFAULT '';
DECLARE query, stmt CHAR(200) DEFAULT '';
DECLARE oldValue, newValue TEXT DEFAULT '';

DECLARE fields CURSOR FOR
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'user'
ORDER BY ordinal_position;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET eof = TRUE;

OPEN fields;

REPEAT
FETCH fields INTO field;
IF NOT eof THEN
SET query = CONCAT('SELECT OLD.', field, ', NEW.', field, ' INTO oldValue, newValue');
PREPARE stmt FROM query;
EXECUTE stmt;
IF BINARY(oldValue) <> BINARY(newValue) THEN
IF rChanges <> '' THEN
SET rChanges := CONCAT(rChanges, '
');
END IF;
SET rChanges := CONCAT(rChanges, field, ': ', oldValue, ' => ', newValue);
END IF;
END IF;
UNTIL eof = TRUE;
END REPEAT;

CLOSE fields;

CALL ChangeNotify('user', OLD.id, rChanges, 'update');
END

这甚至不会保存(除非我有什么问题)。

最佳答案

使用数据库和表尝试下面的代码,它可能会有所帮助。如果对您有帮助,请告诉我。

Call ATESTE('tablename','dbname')

 CREATE PROCEDURE `ATESTE`(tablename varchar(100),schemaname varchar(100))
BEGIN
DECLARE rChanges MEDIUMTEXT;
DECLARE field VARCHAR(50);
DECLARE cmdquery MEDIUMTEXT;
DECLARE oldValue, newValue VARCHAR(50);
DECLARE myfields MEDIUMTEXT;
DECLARE mPos integer;

set myfields = (SELECT group_concat(column_name)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = tablename and table_schema= schemaname
ORDER BY ordinal_position);

set rChanges = '';
set mPos = Position("," in myfields);

myloop: While(mPos > 0) Do

set field = trim(substring(myfields,1,mPos-1));
set myfields = trim(substring(myfields,mPos+1));
set mPos = Position("," in myfields);
set oldValue = CONCAT('old.',field);
set NewValue = CONCAT('new.',field);


IF rChanges <> '' THEN
SET rChanges = CONCAT(rChanges, '\r\n');
END IF;

SET rChanges = CONCAT(rChanges, field, ' : ', oldValue, ' => ', newValue);

End While;

-- select rChanges;

CALL ChangeNotify('user', OLD.id, rChanges, 'update');

END

关于mysql - 使用 MySQL,如何迭代更新触发器中的字段以比较更改日志的新旧值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59055077/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com