Существует предложение MERGE
в нескольких зрелой СУБД для этих случаев. MERGE
- INSERT
и UPDATE
в то же время.
Общий синтаксис Пример:
MERGE INTO TABLE_NAME USING table_reference ON (condition)
WHEN MATCHED THEN
UPDATE SET column1 = value1 [, column2 = value2 ...]
WHEN NOT MATCHED THEN
INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...
Некоторые СУБД, такие как MySQL имеет свой собственный синтаксис с той же идеей. См. Больше в Wikipedia.
Если ваша СУБД не соппует, тогда вы можете написать хранимую процедуру с той же логикой.
Но хранимая процедура или любая другая проверка вашего кода перед вставкой сделают «задержку», и операция станет «неатомной». Это означает, что возможно, что сразу после проверки и перед вставками другая транзакция может сделать дублируемую запись, и вы получите неожиданные дубликаты или экскременты. Чтобы этого избежать, вам нужно заблокировать таблицу перед этой операцией, чтобы получить эксклюзивный доступ к таблице, что может привести к штрафу за порфиману из-за сериализации доступа.
Или вы можете использовать INSERT
с SELECT
, как это:
INSERT (field1, ...) INTO table1
SELECT value1, ...
FROM DUAL -- put a name of analogue of Oracle's DUAL here
WHERE NOT EXISTS (
SELECT 1
FROM table1
WHERE key = :new_key
)
Но, как вы понимаете, это не будет ничего обновлять.
http://stackoverflow.com/q/108403/284240 –