2

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

  • 在行更新之前,检查项目的价格
  • 如果价格与上次价格相比发生了变化,则从另一个具有项目类型和相关表名的表中选择表名、插入项目名的位置。
  • 在选定的表中插入项目名称。

简单地说,我有一个表(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 不存在。

4

3 回答 3

2

回答我自己的问题。 发现在MySQL 触发器中不允许
使用Dynamic SQL此处列出了这些限制。 然而,在 Oracle 中我们可以使用PRAGMA AUTONOMOUS_TRANSACTION在新的上下文中执行查询,因此支持Dynamic SQL是可能的。 此处第 27 点列出的示例。


于 2011-08-01T12:29:50.580 回答
0

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

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

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

于 2011-07-30T05:37:09.790 回答
-1

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

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

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

END IF;
...

如果有不同的项目属性,这个表可以是特定子表的父表。

于 2011-08-05T06:26:29.727 回答