Использование результата SQL-запроса в качестве имени таблицы в триггере MySQL - PullRequest
2 голосов
/ 30 июля 2011

Я должен написать триггер на моей таблице, который будет выполнять следующие функции.

  • Перед обновлением в строке проверьте цену товара
  • Если цена изменилась по сравнению с последней ценой, выберите имя таблицы, в которую следует вставить имя элемента, из другой таблицы, имеющей тип элемента и соответствующее имя таблицы.
  • Вставка элементаимя в выбранной таблице.

Проще говоря, у меня есть таблица ( 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 ]

2 голосов
/ 01 августа 2011

Отвечая на мой вопрос.
Выяснилось, что использование Динамический SQL недопустимо в Триггерах MySQL .
Ограничения перечислены здесь .
Однако это возможно в Oracle, где мы можем использовать PRAGMA AUTONOMOUS_TRANSACTION , который выполняет запрос в новом контексте и, следовательно, поддерживает Динамический SQL .
Пример в списке здесь в Точка 27 .

0 голосов
/ 05 августа 2011

Если это возможно, я бы посоветовал вам немного изменить дизайн. Вместо разных таблиц вы можете создать одну таблицу itemTable.

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

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

END IF;
...

Если существуют разные свойства элемента, эта таблица может быть родительской таблицей для определенных дочерних таблиц.

0 голосов
/ 30 июля 2011

Вы можете CONCAT () ваш оператор INSERT в переменную и выполнить его как PREPARED STATEMENT, что-то вроде

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

afaik это единственный способ обрабатывать динамически сгенерированный SQL в хранимых подпрограммах и триггерах.

...