MySQL: как использовать разделители в триггерах? - PullRequest
0 голосов
/ 16 ноября 2011

Кто-то сказал мне, что мне нужно использовать разделитель в моем триггере.Я смотрю на страницу руководства MySQL и нахожу это в примере;однако, это не в общей документации.

Вот код, который я пытаюсь исправить:

CREATE TRIGGER adult BEFORE INSERT OR UPDATE ON table5.column5
FOR EACH ROW BEGIN
  UPDATE table1 SET column5 = table5.column5 WHERE table5id = table1xtable5.table5id WHERE table1xtable5.table1id = OLD.table1.id$
END$

Честно говоря, я понятия не имею, как это сделать, и документация на http://dev.mysql.com/doc/refman/5.5/en/create-trigger.html кажется ужасно неадекватной ссылкой.Например, когда вы читаете о «old» и «new», он ссылается на «subject table» - таблицу, связанную с триггером.С этим триггером связаны две таблицы, и я на самом деле пытаюсь связать больше таблиц с этим триггером .... При рассмотрении примера кода в строке UPDATE, которая влияет на table4, используются только столбцы внутри table4 (они добавляют 1 к значению).Кроме того, они используют WHERE ~ a3 = NEW.a1.Я не думаю, что этот идентификатор работает таким образом.Не должно быть универсального идентификатора, который бы работал в разных таблицах.Они определенно должны использовать таблицу взаимозависимостей в этом примере для применимости.

Я на самом деле задал похожий вопрос ранее сегодня о том, каким будет хороший метод для этого, но теперь мне просто интересно, еслиесть метод.Спасибо за прочтение.:)

Вот пример триггера, который обновляет другую таблицу, но, похоже, он не использует разделитель:

CREATE TRIGGER mytrigger BEFORE INSERT ON odp 
FOR EACH ROW
  UPDATE total_points SET points = points + NEW.points;

В этом примере не объясняется, какodp и total_points перекрываются.Как мы можем быть уверены, что строка points таблицы total_points является правильной строкой points?Какую строку в таблице points обновит MySQL?x //

Итак, не должно ли быть какого-либо способа указать, какую из строк total_points.points обновить BEFORE INSERT ON odp?

Ответы [ 3 ]

5 голосов
/ 16 ноября 2011

Часть 1

Разделители используются для исходных объектов, таких как хранимая процедура / функция, триггер или событие. Все эти объекты могут иметь код тела в предложении BEGIN ... END.

Все операторы в сценариях MySQL должны заканчиваться разделителем, по умолчанию используется ';'. Но что делать, если исходный объект имеет тело с некоторыми утверждениями, например, g:

INSERT INTO table1 VALUES(1);

CREATE PROCEDURE procedure1()
BEGIN
  SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
  PREPARE stmt2 FROM @s;
  SET @a = 6;
  SET @b = 8;
  EXECUTE stmt2 USING @a, @b;
END;

INSERT INTO table1 VALUES(2);

Сколько государственных деятелей? 3 или 8? Ответ три, потому что скрипт имеет два оператора INSERT и один оператор CREATE PROCEDURE. Как видите, CREATE PROCEDURE также имеет некоторые внутренние утверждения; мы должны сказать клиенту MySQL, что все эти операторы (внутри BEGIN ... END) - являются частью одного оператора; мы можем сделать это с помощью разделителей:

INSERT INTO table1 VALUES(1);

DELIMITER $$

CREATE PROCEDURE procedure1()
BEGIN
  SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
  PREPARE stmt2 FROM @s;
  SET @a = 6;
  SET @b = 8;
  EXECUTE stmt2 USING @a, @b;
END$$

DELIMITER ;

INSERT INTO table1 VALUES(2);

Обратите внимание: если у вашего триггера нет предложения BEGIN ... END, разделители могут быть опущены.


Часть 2

Без разделителей оператор будет проанализирован как -

CREATE PROCEDURE procedure1()
BEGIN
  SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';

вместо -

CREATE PROCEDURE procedure1()
BEGIN
  SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
  PREPARE stmt2 FROM @s;
  SET @a = 6;
  SET @b = 8;
  EXECUTE stmt2 USING @a, @b;
END
0 голосов
/ 16 ноября 2011

Запрос UPDATE, который вы выполняете внутри триггера, является запросом обновления, как и любой другой, за исключением того, что он выполняется внутри триггера. Прямо сейчас вы обновляете ВСЕ записи и увеличиваете поле точек. Если вы хотите ограничить его только определенными записями, которые связаны с тем, что вызвало срабатывание триггера, вам придется добавить это к предложению UPDATE запроса WHERE.

MySQL знает, каково ваше намерение с помощью запроса UPDATE, точно так же, как он не знает, что вы на самом деле имеете в виду, когда выполняете обычные операции вставки / обновления / удаления - вам решать, что именно нужно делать .

В случае триггера INSERT обычно не существует «старой» записи, на которую можно ссылаться, поскольку вы создаете что-то совершенно новое (если только это не вставка ... в ситуации обновления дублированного ключа).

0 голосов
/ 16 ноября 2011

пробег:

delimiter $$

перед запуском CREATE

...