SQL реализация MySQL Server 2005 REPLACE INTO?

голоса
73

MySQL имеет это невероятно полезный еще properitary REPLACE INTOSQL команды.

Может ли это быть легко эмулировать в SQL Server 2005?

Начиная новую транзакцию, делая Select()и затем либо UPDATEили INSERT IGNORE и COMMITвсегда немного боли, особенно при выполнении его в приложении , и поэтому всегда держать 2 версии заявления.

Интересно , если есть простой и универсальный способ реализации такой функции в SQL Server 2005?

Задан 01/08/2008 в 23:13
источник пользователем
На других языках...                            


4 ответов

голоса
53

Это то , что меня раздражает MSSQL ( Rant в моем блоге ). Я хотел MSSQL поддерживается upsert.

Код @ Dillie-O является хорошим способом в более старых версиях SQL (+1 голосование), но она по- прежнему в основном две операции ввода - вывода ( , existsа затем updateили insert)

Там есть немного лучший способ на этот пост , в основном:

--try an update
update tablename 
set field1 = 'new value',
    field2 = 'different value',
    ...
where idfield = 7

--insert if failed
if @@rowcount = 0 and @@error = 0
    insert into tablename 
           ( idfield, field1, field2, ... )
    values ( 7, 'value one', 'another value', ... )

Это сводит его к одной операции ввода-вывода, если это обновление, или два, если вставка.

MS SQL2008 представляет mergeиз SQL: стандарт 2003:

merge tablename as target
using (values ('new value', 'different value'))
    as source (field1, field2)
    on target.idfield = 7
when matched then
    update
    set field1 = source.field1,
        field2 = source.field2,
        ...
when not matched then
    insert ( idfield, field1, field2, ... )
    values ( 7,  source.field1, source.field2, ... )

Теперь это действительно только одна операция ввода-вывода, но ужасный код :-(

Ответил 15/08/2008 d 13:50
источник пользователем

голоса
20

Функциональность вы ищете традиционно называют UPSERT. По крайней мере, зная, что это называется может помочь вам найти то, что вы ищете.

Я не думаю , что SQL Server 2005 имеет какие - либо большие способы сделать это. 2008 вводит оператор MERGE , который можно использовать для достижения этой цели, как показано на: http://www.databasejournal.com/features/mssql/article.php/3739131 или http://blogs.conchango.com/davidportas/archive/ 2007/11 / 14 / SQL-Server-2008-MERGE.aspx

Merge была доступна в бета-версии 2005 года, но они сняли его в финальной версии.

Ответил 01/08/2008 d 23:22
источник пользователем

голоса
15

Что upsert / слияние делает что-то эффект ...

IF EXISTS (SELECT * FROM [Table] WHERE Id = X)
   UPDATE [Table] SET...
ELSE
   INSERT IGNORE  INTO [Table]

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

Ответил 01/08/2008 d 23:31
источник пользователем

голоса
9

Я написал в блоге об этой проблеме .

Суть заключается в том, что если вы хотите дешевые обновления ... и вы хотите быть безопасными для одновременного использования. пытаться:

update t
set hitCount = hitCount + 1
where pk = @id

if @@rowcount < 1 
begin 
   begin tran
      update t with (serializable)
      set hitCount = hitCount + 1
      where pk = @id
      if @@rowcount = 0
      begin
         insert t (pk, hitCount)
         values (@id,1)
      end
   commit tran
end

Таким образом, у вас есть 1 операция для обновления и максимум 3 операций для вставки. поэтому, если вы, как правило, обновляя это безопасный дешевый вариант.

Я хотел бы также быть очень осторожным, чтобы не использовать что-либо, что является небезопасным для одновременного использования. Его очень легко получить первичный ключ нарушения или повторяющиеся строки в производстве.

Ответил 21/09/2008 d 23:05
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more