2016-09-07 3 views
1

MySQL V 5,6MySQL триггер: столбец не является частью обновления не является нулевым

Привет, У меня есть проблема с триггером BEFORE UPDATE: на столе, у меня есть defiend флаг как TINYINT, не равно нулю, значение по умолчанию 1. У меня есть триггер до обновления, который устанавливает этот флаг равным 1 всякий раз, когда строка обновляется. Но мне также нужно в одном процессе явно установить флаг в 0, так что я пытался что

create trigger t BEFORE UPDATE on table for each row 
BEGIN 
IF new.flag is NULL THEN 
    set new.flag = 1 
END IF; 

Проблема: new.flag никогда не нуль. Проверка с помощью

IF new.flag is NULL THEN 
    set new.flag = 1 
ELSEIF new.flag = 0 THEN 
    set new.flag = 3 
END IF; 

установить столбец 3, когда я обновить таблицу без включения флага в запросе обновления. Хуже того, я не могу проверить на пустую строку поставить флаг в 1, как выбрать («» = 0) возвращает истину, если с помощью:

IF new.flag is NULL OR new.flag = '' THEN 
    set new.flag = 1 
END IF; 

Я никогда не может точно установить флаг в 0. Должен ли столбчик, не являющийся частью обновления, иметь значение null в NEW? Что я могу сделать, это изменить конфигурацию mysql?

Благодаря

+2

'new' будет содержать значения, которые строка будет иметь после обновления (и' old' значения ранее). Если вы не зададите его в своем запросе, оно будет иметь значение, которое было ранее ('new' - это не список столбцов, которые вы использовали в запросе на обновление). Вы можете использовать, например. 'set flag = 3' в вашем обновлении-запросе как маркер, который вы хотите установить в своем триггере равным 0. Или, возможно, вы захотите изменить свою логику, общие маркеры обновления - это, например, 'timestamp' с' on update current_timestamp'. – Solarflare

+0

@Solarflare ha, устанавливая поддельное значение, а затем на 0 в ригере, похоже, делает это: IF new.flag_indexation_required = 3 THEN set new.flag_indexation_required = 0; ELSE set new.flag_indexation_required = 1; END IF; Можете ли вы добавить свой ответ, чтобы я мог его принять? – jlb

ответ

1

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

Чтобы сообщить триггеру, что вы хотите явно сбросить значение, вы можете использовать другое неиспользованное (но действительное) значение, чтобы пометить эту информацию, а затем действовать соответствующим образом в триггере, например, в вашем триггере, использовать (при условии подписал TINYINT)

IF new.flag = -1 THEN 
    set new.flag = 0; 
ELSE 
    set new.flag = 1; 
END IF; 

Затем в update запросе

update table set flag = -1; 

установит значение 0, любое другое значение, или не использовать этот столбец в запросе на всех, установит его 1.

Существует альтернативный и более общий подход без триггеров, который похож на ваш флаг. Вы можете использовать столбец

last_update datetime default null on update current_timestamp; 

null в этом столбце будет иметь такое же значение, как flag = 0, любое другое значение будет иметь такое же значение, как flag = 1. Они устанавливаются автоматически. Если вы хотите сбросить свой флаг, вы можете просто использовать

update table set last_update = null; 

Ваш спусковой механизм, конечно, будет работать отлично. Просто убедитесь, что где-то документировали это поведение.

Смежные вопросы