Проверки в триггерах MySQL

Возникла необходимость проверки определенного значения перед добавлением/обновлением его в базе данных.
Есть следующая таблица:
CREATE TABLE `balance` (
	`id` INT(10) NOT NULL AUTO_INCREMENT,
	`item_id` INT(10) NOT NULL DEFAULT '0',
	`place_id` INT(10) NOT NULL DEFAULT '0',
	`count` INT(10) UNSIGNED NOT NULL DEFAULT '0',
	PRIMARY KEY (`id`),
	UNIQUE INDEX `i_pl_itm` (`item_id`, `place_id`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM

И триггер:
BEGIN
	SET @item_id := NEW.`item_id`; 
	SET @place_id := NEW.`place_id`; 
	SET @item_count := NEW.`count`;
	INSERT INTO `balance` (`item_id`,`place_id`,`count`) 
   	VALUES (@item_id,@place_id,@item_count)  
	ON DUPLICATE KEY UPDATE `count`=`count` + @item_count;
END

Вот таблица, в которой учитывается приход/расход товара:
CREATE TABLE `variation` (
	`id` INT(10) NOT NULL AUTO_INCREMENT,
	`person_id` INT(11) NOT NULL DEFAULT '0',
	`place_id` INT(11) NOT NULL DEFAULT '0',
	`item_id` INT(10) NOT NULL DEFAULT '0',
	`date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
	`item_count` INT(11) NOT NULL DEFAULT '0',
	`summ` DOUBLE(10,2) UNSIGNED NOT NULL DEFAULT '0.00',
	PRIMARY KEY (`id`),
	INDEX `i_date` (`date`),
	INDEX `i_item` (`item_id`),
	INDEX `i_place` (`place_id`),
	INDEX `i_person` (`person_id`),
	INDEX `i_dt_pl` (`date`, `place_id`),
	INDEX `i_dt_pn` (`date`, `person_id`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM

На эту таблицу повешен триггер на AFTER INSERT.

Суть в следующем: нельзя ведь продать товара больше, чем есть на складе.
Так вот встал вопрос, как будет лучше проверять значение count перед добавлением в базу данных: в скрипте или в триггере?
Удобнее было бы сделать, конечно, проверку в скрипте.
Но, в любом случае, хочется знать, как в триггере это дело записать? Как «выходить» из триггера в случае ошибки или определенных условий? Насколько знаю, триггер должен по-любому полностью выполниться?

p.s. у меня в триггере-то нет ошибок? :)

p.p.s. или лучше триггер повесить на BEFORE INSERT в таблицу balance?
  • Вопрос задан
  • 7561 просмотр
Пригласить эксперта
Ответы на вопрос 3
hybridcattt
@hybridcattt
IF (statement) THEN… ENDIF
Ответ написан
WebByte
@WebByte
Копайте в сторону транзакций, хранимых процедур и select for update.
И никаких триггеров.
Ответ написан
steff
@steff Автор вопроса
Чуть обновил вопрос.
Триггер написал вот такой:
BEGIN 
	SET @real_count := (SELECT `count` FROM `balance` WHERE
		`item_id` = NEW.`item_id` AND
		`place_id` = NEW.`place_id`);	
	IF (@real_count >= NEW.`item_count`) THEN
		SET @item_id := NEW.`item_id`; 
		SET @place_id := NEW.`place_id`; 
		SET @item_count := NEW.`item_count`;
		INSERT INTO `balance` (`item_id`,`place_id`,`count`) 
	   	VALUES (@item_id,@place_id,@item_count)  
		ON DUPLICATE KEY UPDATE `count`=`count` + @item_count;
	END IF;
END

То есть теперь если уже будет иметься достаточное количество товара, то будут выполняться соответствующие инструкции. Иначе просто ничего не добавится… или… блин. Пойду лучше кофе попью… подумаю…
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы