Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Как правильно создать триггер
 
 автор: LO   (27.03.2007 в 11:41)   письмо автору
 
 

Есть таблица
CREATE TABLE `item_attributes` (
`id` int(10) unsigned NOT NULL auto_increment,
`item_id` int(10) unsigned NOT NULL,
`abbreviation` varchar(255) default NULL,
...
PRIMARY KEY (`id`)
) ;

У меня могут быть несколько записей с одинаковым item_id, и поле abbreviation должно быть уникальным для разных item_id, т.е. abbreviation может повторяться, если у них одинаковый item_id. Т.к. на эти два поля не поставишь уникальный индекс, то решила написать триггер:

CREATE TRIGGER item_attributes_before_insert BEFORE INSERT ON item_attributes
FOR EACH ROW
trig : BEGIN
DECLARE isset_attr INT DEFAULT 0;
SELECT COUNT(id) INTO isset_attr
     FROM item_attributes WHERE abbreviation = NEW.abbreviation AND item_id != NEW.item_id
  IF (isset_attr > 0)
  THEN
     leave trig; 
  END IF;
END

Но с тригерами в MySQL не особо знакома. Какая ошибка в моем коде?

   
 
 автор: cheops   (27.03.2007 в 13:26)   письмо автору
 
   для: LO   (27.03.2007 в 11:41)
 

Что вызывает смущение: триггер работает не правильно или его нельзя создать из-за синтаксической ошибки?

   
 
 автор: LO   (27.03.2007 в 13:49)   письмо автору
 
   для: cheops   (27.03.2007 в 13:26)
 

я не могу его создать
Где-то ошибка ,но я не знаю где именно, ругается на строчку с SELECT

   
 
 автор: cheops   (27.03.2007 в 14:24)   письмо автору
 
   для: LO   (27.03.2007 в 13:49)
 

У вас нет точки с запятой после оператора SELECT.

   
 
 автор: LO   (27.03.2007 в 14:54)   письмо автору
 
   для: cheops   (27.03.2007 в 14:24)
 

да, я исправила, триггер создался, но вот дело в том, что мне нужно именно не выполнить INSERT если выполнится условие. А как это сделать?
Как вызвать в триггерах сообщение об ошибке или что-то в этом роде?

   
 
 автор: Trianon   (27.03.2007 в 15:19)   письмо автору
 
   для: LO   (27.03.2007 в 14:54)
 

Вероятно, нужно просто удалить строку из таблицы new.

   
 
 автор: LO   (27.03.2007 в 15:58)   письмо автору
 
   для: Trianon   (27.03.2007 в 15:19)
 

нет, это не подойдет.
Нужно до INSERT проверить данные.

   
 
 автор: Trianon   (27.03.2007 в 16:14)   письмо автору
 
   для: LO   (27.03.2007 в 15:58)
 

Само собой. Вы же BEFORE INSERT TRIGGER пишете.

   
 
 автор: LO   (27.03.2007 в 16:24)   письмо автору
 
   для: Trianon   (27.03.2007 в 16:14)
 

Вобщем я сделала так:

CREATE TRIGGER item_attributes_before_insert BEFORE INSERT ON ppg_item_attributes
FOR EACH ROW
BEGIN
DECLARE isset_attr INT DEFAULT 0;
SELECT COUNT(item_attributes_id) INTO isset_attr
     FROM ppg_item_attributes WHERE abbreviation = NEW.abbreviation AND item_id != NEW.item_id;
  IF (isset_attr > 0)
  THEN
    SET NEW.item_id = NULL; 
  END IF;
END

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

   
 
 автор: Trianon   (27.03.2007 в 18:00)   письмо автору
 
   для: LO   (27.03.2007 в 16:24)
 

так а вариант

CREATE TRIGGER item_attributes_before_insert BEFORE INSERT ON ppg_item_attributes 
FOR EACH ROW 
BEGIN 
DECLARE isset_attr INT DEFAULT 0; 
SELECT COUNT(item_attributes_id) INTO isset_attr 
     FROM ppg_item_attributes WHERE abbreviation = NEW.abbreviation AND item_id != NEW.item_id; 
  IF (isset_attr > 0) 
  THEN 
    DELETE FROM NEW;
  END IF; 
END

не проходит?

   
 
 автор: LO   (27.03.2007 в 18:26)   письмо автору
 
   для: Trianon   (27.03.2007 в 18:00)
 

проверяла, что бы я не вводила, хоть и допустимые данные мне выдается ошибка
#1146 - Table 'db.NEW' doesn't exist

   
 
 автор: Trianon   (27.03.2007 в 13:39)   письмо автору
 
   для: LO   (27.03.2007 в 11:41)
 

Вот эта часть
...могут быть несколько записей с одинаковым item_id, и поле abbreviation должно быть уникальным для разных item_id, т.е. abbreviation может повторяться, если у них одинаковый item_id. Т.к. на эти два поля не поставишь уникальный индекс...
осталась для меня непонятной.

Как связаны поля item_id и abbreviation? Если одно является первичным ключом для другого (а такая мысль напрашивается из прочтенного) то почему это отношение не выведено в отдельную таблицу?

   
 
 автор: LO   (27.03.2007 в 13:47)   письмо автору
 
   для: Trianon   (27.03.2007 в 13:39)
 

это означает, что могут быть такие записи:
id.......item_id......abbreviation
1........1................A
2........1................NULL
3........1.................A - может,
Но не может быть таких записей
1........1................A
2........1................NULL
3........2.................A - не может быть, т.к. такая аббревиатура уже принадлежит другому item_id

   
 
 автор: Trianon   (27.03.2007 в 14:00)   письмо автору
 
   для: LO   (27.03.2007 в 13:47)
 

таблица естественным образом раскладывается на
items(id, abbrev NULL)
и
attributes(id, item_id)

ну или если NULL и не NULL обязаны сосуществовать независимо, то
attributes(id, item_id, is_abbreviated)

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования