在mysql触发器中使用SQL查询结果作为表名

在mysql触发器中使用SQL查询结果作为表名,mysql,triggers,tablename,Mysql,Triggers,Tablename,我必须在我的表上写一个触发器,它将执行以下功能 在行上更新之前,请检查项目的价格 如果价格已从上次价格更改,则从另一个具有项目类型和关联表名的表中选择表名,在其中插入项目名 在所选表中插入项目名称 简单地说,我有一个表(TypeNameTable),它有项目类别和相应的表名,如果项目的价格发生了变化,那么我必须从TypeNameTable中获取表名,并将项目名插入表中,这是从TypeNameTable中检索到的。 动态获取表名时,我无法插入到表中。请建议怎么做。以下是我正在做的: BEGIN

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

  • 在行上更新之前,请检查项目的价格
  • 如果价格已从上次价格更改,则从另一个具有项目类型和关联表名的表中选择表名,在其中插入项目名
  • 在所选表中插入项目名称
简单地说,我有一个表(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不存在

您可以CONCAT()将INSERT语句插入到变量中,并将其作为准备好的语句执行,例如

...
SET @sql := CONCAT( 'INSERT INTO ', itemTableName, ' ... ' );
PREPARE stmt1 FROM @sql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
...
这是在存储的例程和触发器中处理动态生成的SQL的唯一方法。

回答我自己的问题。
发现在MySQL触发器中不允许使用动态SQL
列出了限制条件。
但是,在Oracle中,我们可以使用PRAGMA autonomy_TRANSACTION在新上下文中执行查询,因此支持动态SQL

第27点列出的示例如果可能,我建议您稍微更改一下设计。您可以创建一个表,而不是不同的表
itemTable

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

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

END IF;
...

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

您有足够的代表知道如何使用而不是HTML@OMG小马:很抱歉格式不好。我真的被这个问题困住了,想不出其他任何东西。我在这样使用时遇到以下错误:错误1336:存储函数或触发器中不允许使用动态SQL,我不知道这仅限于存储过程;对不起,我不知道MySQL触发器不能执行动态SQL语句。即使该语句是从触发器正在调用的存储过程中触发的。您询问了MySQL,但您的答案是关于Oracle的。@Devart我告诉过您,在MySQL中这是不可能的,但Oracle支持动态SQL。因此,您本想使用MySQL,但后来选择了Oracle。但是,为什么不想更改数据库设计呢?如果可能,请不要在行中存储表名。使用表关系。