SELECT LAST_INSERT_ID() Не работает с BIGINT в MySQL 5.6.11 при использовании триггера

Я публикую новый вопрос после моего предыдущего сообщения "SELECT LAST_INSERT_ID() Не работает с BIGINT в MySQL 5.6.11"

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

Итак, в основном моя проблема заключается в том, что при вызове LAST_INSERT_ID() после оператора INSERT он возвращает 0, потому что у меня есть BeforeInsert в качестве триггера для этой таблицы. Если я закомментирую этот триггер, он будет работать нормально, и LAST_INSERT_ID() даст мне правильный номер.

Любые идеи, как преодолеть эту проблему? Ниже находится триггер

DELIMITER $$

USE `mydb`$$

CREATE
DEFINER=`root`@`%`
TRIGGER `mydb`.`Booking_BINS`
BEFORE INSERT ON `mydb`.`Booking`
FOR EACH ROW
-- Edit trigger body code below this line. Do not edit lines above this one

BEGIN

DECLARE iNextBookingId INT;
SET iNextBookingId = (SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE     TABLE_SCHEMA=DATABASE() AND TABLE_NAME='Booking');
SET NEW.BookingId = iNextBookingId; 

INSERT INTO AuditTrail  (AuditTrailId,UserId,ActionType,TableName,RowKey,FieldName,OldValue,NewValue,LoggedOn) VALUES
(UUID(),NEW.LastChangedBy,'INSERT','Booking',NEW.BookingId,'HotelId',NULL,NEW.HotelId,NOW()),
(UUID(),NEW.LastChangedBy,'INSERT','Booking',NEW.BookingId,'AgentId',NULL,NEW.AgentId,NOW()),
(UUID(),NEW.LastChangedBy,'INSERT','Booking',NEW.BookingId,'SupplierId',NULL,NEW.SupplierId,NOW());


 END$$

person neildt    schedule 05.07.2013    source источник
comment
Можете ли вы включить определение вашего триггера?   -  person eggyal    schedule 05.07.2013
comment
Обновил мой вопрос с триггером   -  person neildt    schedule 05.07.2013
comment
Небеса, зачем ты это делаешь?!? Почему бы не позволить MySQL установить значение поля AUTO_INCREMENT для вас, а затем выполнять вставки FK (используя LAST_INSERT_ID() или аналогичный через API) впоследствии, в той же транзакции, если это необходимо?   -  person eggyal    schedule 05.07.2013
comment
Или, может быть, я мог бы просто переместить триггер на событие After Insert?   -  person neildt    schedule 05.07.2013
comment
@eggyal Кроме того, я разрешаю MySQL устанавливать значение AUTO_INCREMENT в моем обычном операторе INSERT. Приведенный выше триггер проверяет все, что добавлено в таблицу.   -  person neildt    schedule 05.07.2013
comment
SET NEW.BookingId = iNextBookingId; - это бит, с которым я не согласен. Я бы избавился от всего этого и просто поместил оператор INSERT ... непосредственно в триггер AFTER INSERT, если такая конструкция вообще необходима.   -  person eggyal    schedule 05.07.2013
comment
Хорошо, я согласен, я могу переместить его в триггер AfterInsert. Я предполагаю, что именно это вызывает проблему, которую я изложил в вопросе выше.   -  person neildt    schedule 05.07.2013


Ответы (1)


Вы создаете состояние гонки, предполагая, что INFORMATION_SCHEMA.TABLES.AUTO_INCREMENT можно использовать как NEW.BookingId. Как только у вас будет более одного сеанса, запускающего этот триггер одновременно, у вас возникнут проблемы, поскольку оба сеанса будут пытаться присвоить BookingId одно и то же значение.

Кроме того, аудит вставок в триггере BEFORE сопряжен с риском, поскольку вставка может завершиться неудачей по разным причинам, и тогда вы можете получить фантомные данные аудита.

Вы должны переместить одитинг в триггер ПОСЛЕ. Таким образом, вы будете знать, что INSERT выполнен успешно, и автоматически увеличивающийся идентификатор BookingId будет сгенерирован обычным способом.

person Bill Karwin    schedule 05.07.2013