0

如何将 NEW/OLD 数据放入没有文件名的临时表中。我试过创建触发器,像这样的过程,但它失败了:


CREATE TRIGGER `after_insert` AFTER INSERT
ON `master`
FOR EACH ROW BEGIN
    CREATE TEMPORARY TABLE after_insert_trigger_temp_table ENGINE=MEMORY 
    AS (SELECT NEW.*);
    CALL after_insert_action();
END$$


CREATE PROCEDURE `after_insert_action`()
BEGIN
    INSERT INTO `slave` (`name`,`detail`)
    SELECT `name`,`detail` FROM after_insert_trigger_temp_table;
END$$

4

1 回答 1

3

你看到它说的部分FOR EACH ROW......

下面的语句FOR EACH ROW定义了每次触发器激活时要执行的语句,触发语句影响的每一行都会发生一次。-- http://dev.mysql.com/doc/refman/5.5/en/trigger-syntax.html (强调)

因此,您建议为使用触发器插入表中的每一行NEW创建一个新的临时表,以某种方式访问​​所有使用. *插入该表,然后调用存储过程,并通过从该临时表中选择两列(大概您知道在原始表中)插入到不同的表中。在某些时候,临时表当然需要消失,因为如果您在一个查询或一个会话中向表中插入超过 1 行,那么您正在尝试创建一个与一个同名的临时表已由您的会话拥有。

我从来没有在触发器或文档中遇到过 OLD.* 或 NEW.* 包罗万象,无论如何,除了可能避免输入两个列名或更改的能力之外,您根本不清楚您要完成什么您在不更新此触发器的情况下使用存储过程跟踪的内容。

但是对于触发器,您需要牢记的一个关键设计因素是,它们应该尽可能高效地执行尽可能少的操作,因为如果您不遵守此规则,它们很有可能成为性能问题。

想到了几种替代方法,因为根据问题中的细节临时表没有意义:

选项1:

CREATE TRIGGER `after_insert` AFTER INSERT ON `master` FOR EACH ROW 
BEGIN
    INSERT INTO `slave` (`name`,`detail`) VALUES (NEW.`name`,NEW.`detail`);
END $$

选项 2:

CREATE TRIGGER `after_insert` AFTER INSERT ON `master` FOR EACH ROW 
BEGIN
    CALL after_insert_action(NEW.`name`,NEW.`detail`);
END $$


CREATE PROCEDURE `after_insert_action`(in new_name TEXT, in new_detail TEXT)
# you may want to use more appropriate datatypes instead of TEXT
# but this should work as written as long as those columns are no larger than TEXT
BEGIN
    INSERT INTO `slave` (`name`,`detail`) VALUES (new_name, new_detail);
END$$
于 2013-02-23T20:12:26.623 回答