Mysql триггер проблема (я думаю, что это увольнение) - PullRequest
0 голосов
/ 01 мая 2011

У меня проблема с триггером в базе данных mysql. У меня есть такая таблица:

id int not null auto_increment (PK)
parent_id int not null,
rank int not null

То, что я пытаюсь сделать, это использовать триггер, чтобы обновить ранг до следующего наивысшего +10, когда они имеют одинаковый parent_id, но это, похоже, не работает.

DELIMITER $$
DROP TRIGGER IF EXISTS after_insert $$
create trigger after_insert 
after insert on mytable
FOR EACH row
BEGIN

  IF EXISTS (SELECT rank FROM mytable WHERE parent_id = new.parent_id AND id != new.id ORDER BY rank DESC LIMIT 1) THEN
  UPDATE mytable SET rank  = 10
  WHERE id = new.id;
  ELSE
  UPDATE mytable SET rank = 20
  WHERE id = new.id;
  END IF;   

END
$$

Я попытался установить новый ранг для переменной и вызвать оператор обновления с помощью этого, и снова это не сработало. Я даже создал еще одну таблицу, чтобы регистрировать, какие значения были выбраны, и это прекрасно работало, поэтому я не совсем понимаю, что происходит. Является ли это случаем, хотя триггер «ПОСЛЕ ВСТАВКИ», вставка фактически не произошла, поэтому она не может обновить только что вставленную строку? Еще одна причина, по которой я спрашиваю об этом, заключается в том, что я даже пытался обновить ранг до различных значений, например, 1 и 2, в зависимости от того, к какому выражению он относится, но всегда заканчивается значением 0.

Ответы [ 2 ]

2 голосов
/ 01 мая 2011

Я думаю, что вы на правильном пути с этой мыслью:

Это случай, хотя триггер "ПОСЛЕ ВСТАВКИ", вставка на самом деле не произошла, поэтому она можетt обновить строку, которую он только что вставил?

Из FAQ :

B.5.9: Могут ли триггеры обращаться к таблицам?

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

Документация нене ясно, что то, что вы делаете, не сработает.OTOH, документация не ясна, что то, что вы пытаетесь сделать, тоже будет работать.

Я думаю, вам было бы лучше использовать триггер BEFORE INSERT и установить там NEW.rank.Тогда новая строка будет иметь правильное значение rank, когда она будет вставлена ​​в таблицу, а не исправлена ​​после нее.Кроме того, вы сможете упростить проверку своего существования до следующего:

EXISTS(SELECT rank FROM mytable WHERE parent_id = new.parent_id)

, поскольку NEW.id не будет иметь полезного значения, и новая строка в любом случае не будет в таблице;ORDER BY и LIMIT также не нужны, так как вы просто проверяете, существует ли что-то, поэтому я их убрал.

Триггер BEFORE INSERT, кажется, все равно лучше соответствует вашим намерениям, и это даст вам правильные данные, как только они будут вставлены в вашу таблицу.

1 голос
/ 01 мая 2011

Если вы хотите, чтобы звание было установлено на +10 больше, чем наивысшее звание "брата", вы можете использовать:

DELIMITER $$
DROP TRIGGER IF EXISTS whatever $$
create trigger whatever
BEFORE INSERT ON mytable
FOR EACH row
BEGIN

  SET NEW.rank = 10 + COALESCE( 
      ( SELECT max(rank)
        FROM mytable
        WHERE parent_id = NEW.parent_id
      ), 0 ) ;   

END
$$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...