我有一个包含这个的触发器:
SET v1 = CONCAT_WS(',',NEW.ID, NEW.Name, NEW.Type, NEW.Value);
可以将其简化为类似这样以包含整个新行吗?:
SET v1 = CONCAT_WS(',',NEW.*);
(我已经尝试了上述的变体,但是它们会导致语法错误)
谢谢
不,没有简单的方法可以做到这一点。您必须引用每一列。
唯一真正的解决方法是使用表元数据来帮助您生成所需的语句,然后将该语句包含在您的过程中。
即使可能,您也不希望在 TRIGGER 中动态执行此操作。
SELECT CONCAT('NEW.`',GROUP_CONCAT(c.column_name
ORDER BY ORDINAL_POSITION SEPARATOR '`,NEW.`'),'`')
FROM information_schema.columns
WHERE table_schema = DATABASE()
AND table_name = 'mytable'
这应该会给你一个看起来像这样的字符串:
NEW.`ID`,NEW.`Name`,NEW.`Type`,NEW.`Value`
您可以将其粘贴到触发器主体中。(当然你可以扩展 CONCAT 来生成整行。)
缺点是当新列添加到表中时,不会自动包含这些列;这将需要更改触发器。如果一列被删除或重命名,您的触发器将开始抛出异常;再次需要修复触发器。
更新
问:如何将此字符串转换为 MySQL 查询?
@query = "CONCAT_WS(',','CCC','64',NEW.Record,NEW.ID,NEW.Name,NEW.User_ID,NEW.State_Record,NEW.Hash);"
我不会将其转换为查询。我只是将它用作触发器主体中的静态代码行(没有双引号),就像您在触发器中的原始语句一样。
SET v1 = CONCAT_WS(',','CCC','64',NEW.Record,NEW.ID,NEW.Name,NEW.User_ID,NEW.State_Record,NEW.Hash);
(不清楚你打算用那个字符串做什么。)
如果您尝试创建一个 SELECT 语句,您可以尝试从字符串末尾删除该分号,并在其前面添加一个 SELECT 关键字。但我不认为是新的。在该上下文中将识别对当前行的列值的引用。这可能会发生,但您需要进行测试。
如果我需要做类似的事情,我会使用用户变量来做,
SET @new_id = NEW.ID;
SET @new_name = NEW.Name;
SELECT @new_id, @new_name
我完全不清楚您将如何处理查询返回的结果集,例如。如果您尝试审核对表的更改,规范模式是将列值插入到更改日志表中,
INSERT INTO mytable_changelog (ID, Name) VALUES (NEW.ID, NEW.Name);
这实际上取决于您要完成的工作。