SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 24.02.2011 02:16:38

NT Man
Участник
Зарегистрирован: 07.06.2008
Сообщений: 16

Получение LAST_INSERT_ID() вне триггера при использовании LAST_INSERT_ID() в триггере

Есть несколько таблиц, одна как-бы корневая таблица workflow_documents, она имеет первичный ключ id_document который заполняется авто инкрементом.

CREATE TABLE `workflow_documents` (
  `id_document` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `id_process` INT(11) UNSIGNED NOT NULL,
  PRIMARY KEY (`id_document`)
) ENGINE=INNODB DEFAULT CHARSET=utf8


Остальные расширяют workflow_documents, для этого в каждой есть первичный ключ id_document, но он является вторичным ключом в workflow_documents, соответственно никакого AUTO_INCREMENT нет.

CREATE TABLE `bonus_prod` (
  `id_document` INT(10) UNSIGNED NOT NULL,
  `customer_description` VARCHAR(255) DEFAULT NULL,
  `id_user` INT(11) UNSIGNED NOT NULL,
  PRIMARY KEY (`id_document`),
  CONSTRAINT `FK_bonus_prod` FOREIGN KEY (`id_document`) REFERENCES `workflow_documents` (`id_document`) ON DELETE CASCADE
) ENGINE=INNODB DEFAULT CHARSET=utf8


Для заполнения id_document на дочерних таблицах висит триггер, который анализирует NEW.id_document и если тот 0, то вставляет запись сначала в workflow_documents, затем получает id вновь вставленной записи через LAST_INSERT_ID() и делает нужную подстановку.

DELIMITER $$
CREATE TRIGGER `bonus_prod_insert` BEFORE INSERT ON `bonus_prod`
FOR EACH ROW BEGIN
    IF NEW.id_document = 0 THEN    
        INSERT INTO workflow_documents (id_process) VALUES (3);
        SET NEW.id_document = LAST_INSERT_ID();        
    END IF;    
    SET @DOCUMENT_ID = NEW.id_document;    
END;$$
DELIMITER ;


Проблема в том что мне нужно получать LAST_INSERT_ID() на сервере приложений, а тут выяснилось, что если в триггере есть LAST_INSERT_ID(), то по выходу из него LAST_INSERT_ID() восстанавливается предыдущим значением в итоге я вижу совсем не то. Как видно из моего кода я сделал временное решение в виде заполнения глобальной переменной @DOCUMENT_ID значением LAST_INSERT_ID() внутри триггера, но это решение видится мне диким костылем.
Есть ли более красивый обход данной проблемы? Требуется получать реальный LAST_INSERT_ID() вне триггера.

Отредактированно NT Man (24.02.2011 02:17:41)

Неактивен

 

#2 24.02.2011 23:25:38

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Получение LAST_INSERT_ID() вне триггера при использовании LAST_INSERT_ID() в триггере

Из триггера нельзя вернуть правильное значение LAST_INSERT_ID (хотя бы потому,
что если Вы вставите несколько строк в bonus_prod, не понятно будет, как переда-
вать эту информацию).

В данном случае, мне кажется, что Ваш способ верный. Чтобы не сильно переписы-
вать код, можно после выполнения INSERT добавить явно
SELECT LAST_INSERT_ID(@DOCUMENT_ID).

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson