我要在我的桌子上写一个 触发器 ,它将执行以下功能。
简单地说我有一个表( 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不存在。
答案 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;
...
如果有不同的项属性,则此表可以是特定子表的父表。