Как правильно / самый быстрый способ обновить / вставить запись в SQL (Firebird / MySql)
Вопрос
Мне нужен какой-то SQL, чтобы обновить запись в базе данных, если она существует, и вставить ее, когда ее нет, оглядываясь вокруг, можно найти несколько решений для этого, но я не знаю, каковы правильные / принятые способы сделай это.
В идеале мне бы хотелось, чтобы он работал как на Firebird 2, так и на MySQL 5, поскольку обновление нужно будет запускать для обеих баз данных, и было бы проще, если бы один и тот же SQL работал на обеих, если бы он работал на большем количестве баз данных, которые могли бы быть плюсом.
Скорость и надежность также влияют на надежность и скорость в этом случае, но потенциально могут использоваться для быстрого обновления 1000 записей (по разным таблицам).
какие-либо замечания?
Решение
Вы должны использовать что-то вроде этого:
BEGIN TRANSACTION
IF EXISTS (SELECT * FROM the_table WHERE pk = 'whatever')
UPDATE the_table SET data = 'stuff' WHERE pk = 'whatever'
ELSE
INSERT INTO the_table (pk, data) VALUES ('whatever', 'stuff')
COMMIT
Или это, но отправьте их отдельно и игнорируйте все ошибки из INSERT о нарушении ограничений первичного ключа:
INSERT INTO the_table (pk, data) VALUES ('whatever', 'stuff')
UPDATE the_table SET data = 'stuff' WHERE pk = 'whatever'
Другие советы
В Firebird 2.1 вы можете использовать ОБНОВЛЕНИЕ ИЛИ ВСТАВИТЬ для простых случаев или MERGE для более сложных сценариев.
Для MySQL попробуйте команду REPLACE
: http: / /dev.mysql.com/doc/refman/5.0/en/replace.html р>
(См. комментарий к этому ответу Милана Бабускова для эквивалентов в Firebird.)
В Firebird до версии 2.1 вы можете использовать этот хитрый способ:
insert into table (id, a, b, c) values (:id, :a, :b, :c)
when SQLCODE -803
do
begin
update table set a = :a, b = :b, c = :c where id = :id;
end;
REPLACE работает точно так же, как INSERT, за исключением того, что если старая строка в таблице имеет то же значение, что и новая строка для PRIMARY KEY или UNIQUE индекса, старая строка удаляется перед вставкой новой строки.
Синтаксис:
ЗАМЕНИТЕ [LOW_PRIORITY | ЗАДЕРЖИВАЕТСЯ] [INTO] tbl_name [(col_name, ...)]
{ VALUES | VALUE}
({expr | DEFAULT},...),(...),...
Принимая во внимание: Лучше избегать REPLACE при работе с ограничениями.
Я использовал INSERT в MySQL обновить строки с помощью:
INSERT INTO table () VALUES () ON DUPLICATE KEY UPDATE key
Но вы не можете использовать автоматически сгенерированный ключ. Р>