2014-09-18 3 views
1

Был задан почти одинаковый вопрос: here с использованием оператора IF, но он не получил ответ от ответа, просто предложил пойти here, где не используются инструкции IF. Я попытался написать как инструкцию IF, так и условное выражение, используя последнюю ссылку, но я застрял (см. Ниже).Условная вставка на основе LAST_INSERT_ID

Я хочу иметь возможность условно вставлять строку только в том случае, если предыдущая попытка вставки фактически вставила строку (ROW_COUNT > 0). В предыдущей вставке могли быть дублированные данные, поэтому я намеренно устанавливаю значение LAST_INSERT_ID в значение null, поэтому последующие дочерние вставки не могут произойти с этим LAST_INSERT_ID. Сценарий SQL создается сценарием C#, поэтому было бы очень возможно, что LAST_INSERT_ID не указывает на то, что вы ожидаете.

Вот очень небольшой пример сценария сгенерированный код (есть ~ 3 миллиона строк в конечной базе данных):

SET @Vendors_Vendor_ID = (SELECT vendor_ID FROM VENDORS WHERE vendorName = 'PCA'); 
INSERT IGNORE INTO PCBID (PCBID, PCBDrawing, AssemblyDrawing, PONumber, Vendors_Vendor_ID) 
VALUES (11001, '10405', '41606', '091557.5', @Vendors_Vendor_ID); 
SET @eventType_ID = (SELECT EVENTTYPE_ID FROM EVENTTYPES WHERE EVENTTYPE = 'Creation'); 
SET @USER = 'CTHOMAS'; 
INSERT IGNORE INTO EVENTS (PCBID, EVENTTYPE_ID, DATETIME, USER) 
VALUES (11001, @eventType_ID, '2009-06-15T13:15:27', @USER); 
SET @EVENT_ID = IF(ROW_COUNT() > 0, LAST_INSERT_ID(), null); 
-- THIS DOES NOT WORK 
SELECT IF(@EVENT_ID != null, 
    INSERT INTO EVENTDETAILS (EVENT_ID, ITEMNAME, ITEMVALUE) 
    VALUES (@EVENT_ID, 'Notes', 'WO#89574'), 
    null); 

-- THIS DOESN'T WORK EITHER 
INSERT INTO EVENTDETAILS (EVENT_ID, ITEMNAME, ITEMVALUE) 
SELECT @EVENT_ID, 'Notes', 'WO#89574' 
WHERE @EVENT_ID != null; 

PCBID таблица не является проблемой для дублирования данных, а События таблица содержит составной уникальный ключ, который предотвращает дубликатов данных с помощью INSERT IGNORE:

CREATE TABLE IF NOT EXISTS `uniqueTest`.`events` (
`Event_ID` INT(11) NOT NULL AUTO_INCREMENT , 
`PCBID` INT(11) NOT NULL , 
`EventType_ID` INT(11) NOT NULL , 
`DateTime` DATETIME NOT NULL , 
`User` VARCHAR(45) NOT NULL , 
PRIMARY KEY (`Event_ID`) , 
UNIQUE KEY `PDU_Index` (`PCBID`, `DateTime`, `User`), 

Проблема: Мне нужно сделать условную вставку на основе предыдущей попытки вставки в таблицу Events, если она была проигнорирована (поскольку это дубликаты данных), не вставляйте ни одной дочерней строки. В настоящее время нет возможности сделать уникальные данные EventDetail, может быть несколько строк законных данных на основе данного Event_ID.

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

+0

Вы можете использовать триггер AFTER INSERT и оставить игнорировать. Если у вас есть повторяющаяся запись ключа, вставка не будет выполнена, и триггер не будет выполнен. – Gervs

ответ

1

Ваша вторая попытка была почти права. Вы должны проверить значения NULL с IS NOT NULL. Так что используйте

INSERT INTO EVENTDETAILS (EVENT_ID, ITEMNAME, ITEMVALUE) 
SELECT @EVENT_ID, 'Notes', 'WO#89574' FROM DUAL 
WHERE @EVENT_ID IS NOT NULL; -- instead of != 

или

INSERT INTO EVENTDETAILS (EVENT_ID, ITEMNAME, ITEMVALUE) 
SELECT t.* FROM (
    SELECT @EVENT_ID, 'Notes', 'WO#89574' 
) t 
WHERE @EVENT_ID IS NOT NULL; -- instead of != 

первый не может работать:

-- THIS DOES NOT WORK 
SELECT IF(@EVENT_ID != null, 
    INSERT INTO EVENTDETAILS (EVENT_ID, ITEMNAME, ITEMVALUE) ... 

, потому что синтаксис IF является

IF (expr1, expr2, expr3)

Если expr1 имеет значение TRUE (expr1 <> 0 и expr1 <> NULL), то IF() возвращает expr2; в противном случае он возвращает expr3. IF() возвращает числовое или строковое значение, в зависимости от контекста, в котором он используется.

Условное исполнение утверждений возможно только в stored routines.IF syntax хранимых процедур позволит что-то вроде

IF @EVENT_ID IS NOT NULL THEN 
    INSERT INTO EVENTDETAILS (EVENT_ID, ITEMNAME, ITEMVALUE) ... 
END IF 

Вы должны различать эти обе версии синтаксиса.

+0

Спасибо за помощь, я ценю это. Я получаю: «Синтаксическая ошибка, неожиданная ГДЕ, ожидающая END_OF_INPUT или«; »в предложении WHERE, используя ваш пример выше. – delliottg

+0

@ delliottg Плохо, я не читал достаточно внимательно. Если вы используете предложение WHERE, у вас должно быть предложение 'FROM'. Вы можете использовать 'FROM DUAL', заимствованные из Oracle или использовать подзапрос. Оба указали в моем редактировании. – VMai

+0

Не беспокойтесь. Я должен был изменить «a» перед предписанием WHERE на «t», что заставляет его работать отлично, спасибо! Можете ли вы отредактировать свой ответ? Это не позволит мне сделать это небольшое изменение. – delliottg

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