在mysql触发器中使用SQL Query的结果作为表名

时间:2011-07-30 05:06:12

标签: mysql triggers tablename

我要在我的桌子上写一个 触发器 ,它将执行以下功能。

  • 在行更新之前,请检查项目的价格
  • 如果价格已从上一个价格发生变化,则从具有项目类型和关联表格名称的另一个表格中选择表格名称,在何处插入项目名称。
  • 在所选表格中插入项目名称。

简单地说我有一个表( TypeNameTable )具有项目类别和相应的表名称,如果项目的价格已经更改,那么我将从获取表名称TypeNameTable 并在表格中插入项目名称,该名称是从 TypeNameTable 中检索的。 当我动态获取表名时,我无法插入表中。请建议怎么做。这就是我正在做的事情:

BEGIN

  #declare countryTableName varchar(50);
  declare itemPrice int;
  declare itemTableName text;

  IF (New.Price != Old.Price) THEN
    SET countryTableName = (select `ItemManager`.`TypeNames`.`TypeTableName` 
                              from `ItemManager`.`TypeNames` 
                             where `ItemManager`.`TypeNames`.`ItemType` = NEW.ItemType);

   INSERT INTO `ItemManager`.itemTableName
     ( `ItemName`, `ItemPrice`,
   VALUES
    ( NEW.Name, New.Price );

  END IF;
END$$

我收到错误

  

ItemManager。itemTableName不存在。

3 个答案:

答案 0 :(得分:2)

回答我自己的问题。
MySQL触发器 中不允许使用动态SQL
列出限制here
但是在Oracle中我们可以使用 PRAGMA AUTONOMOUS_TRANSACTION 在新的上下文中执行查询,因此支持动态SQL 。 在 第27点 列出here的示例。

答案 1 :(得分:0)

您可以将INSERT语句CONCAT()转换为变量并将其作为PREPARED STATEMENT执行,例如

...
SET @sql := CONCAT( 'INSERT INTO ', itemTableName, ' ... ' );
PREPARE stmt1 FROM @sql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
...

afaik这是在存储的例程和触发器中处理动态生成的SQL的唯一方法。

答案 2 :(得分:-1)

如果有可能,我建议你稍微改变设计。您可以创建一个表itemTable来代替不同的表。

...
IF (New.Price != Old.Price) THEN

 INSERT INTO `ItemManager`.`itemTable`
   ( `ItemName`, `ItemPrice`,
 VALUES
  ( NEW.Name, New.Price );

END IF;
...

如果有不同的项属性,则此表可以是特定子表的父表。