【问题标题】:Select entire [NEW] Row in Before Insert Trigger MySQL在插入触发器MySQL之前选择整个[NEW]行
【发布时间】:2012-07-16 22:07:11
【问题描述】:

我有一个包含这个的触发器:

SET v1 = CONCAT_WS(',',NEW.ID, NEW.Name, NEW.Type, NEW.Value);

可以将其简化为类似这样以包含整个新行吗?:

SET v1 = CONCAT_WS(',',NEW.*);

(我已经尝试了上述的变体,但是它们会导致语法错误)

谢谢

【问题讨论】:

标签: mysql triggers


【解决方案1】:

不,没有简单的方法可以做到这一点。您必须引用每一列。

唯一真正的解决方法是使用表元数据来帮助您生成所需的语句,然后将该语句包含在您的过程中。

您不希望在 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);

这真的取决于你想要完成什么。

【讨论】:

  • 您好,感谢您的回复。基于此,我设法生成了一个我需要的查询字符串并将其分配给一个变量,但是如何将其转换为 MySQL 查询? @query = "CONCAT_WS(',','CCC', '64', NEW.Record,NEW.ID,NEW.Name,NEW.User_ID,NEW.State_Record,NEW.Hash);"
猜你喜欢
  • 2017-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-30
  • 1970-01-01
  • 2012-12-11
  • 2020-09-07
相关资源
最近更新 更多