SQL Server 2005 implementação do MySQL REPLACE INTO?

votos
73

MySQL tem esta incrivelmente útil ainda properitary REPLACE INTOcomando SQL.

Isso pode ser facilmente emulado no SQL Server 2005?

Começando uma nova transação, fazendo um Select()e então UPDATEou INSERT IGNORE e COMMITé sempre um pouco de dor, especialmente quando fazê-lo na aplicação e, portanto, sempre mantendo 2 versões do comunicado.

Gostaria de saber se existe uma maneira fácil e universal forma de implementar tal função em SQL Server 2005?

Publicado 01/08/2008 em 23:13
fonte usuário
Em outras línguas...                            


4 respostas

votos
53

Isso é algo que me irrita sobre MSSQL ( discurso no meu blog ). Desejo MSSQL suportado upsert.

Código de @ Dillie-O é uma boa maneira em versões SQL mais velhos (1 voto), mas ainda é basicamente duas operações de IO (a existse depois a updateou insert)

Há um pouco melhor maneira de este post , basicamente:

--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', ... )

Isto reduz a um operações de IO se é uma atualização, ou dois, se uma inserção.

MS SQL2008 introduz mergedo padrão 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, ... )

Agora é realmente apenas uma operação IO, mas o código terrível :-(

Respondeu 15/08/2008 em 13:50
fonte usuário

votos
20

A funcionalidade que você está procurando é tradicionalmente chamado de UPSERT. Pelo menos saber o que é chamado pode ajudá-lo a encontrar o que você está procurando.

Eu não acho que o SQL Server 2005 tem quaisquer grandes maneiras de fazer isso. 2008 introduz a instrução MERGE que pode ser usado para alcançar este objetivo, como mostrado na: http://www.databasejournal.com/features/mssql/article.php/3739131 ou http://blogs.conchango.com/davidportas/archive/ 2007/11 / 14 / SQL-Server-2008-MERGE.aspx

Mesclar estava disponível no beta de 2005, mas eles removeram-lo na versão final.

Respondeu 01/08/2008 em 23:22
fonte usuário

votos
15

O que o upsert / merge está fazendo é algo para o efeito de ...

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

Portanto, esperamos que a combinação desses artigos e este código pseudo pode obter as coisas em movimento.

Respondeu 01/08/2008 em 23:31
fonte usuário

votos
9

Eu escrevi um post sobre este assunto .

A linha inferior é que se você quiser atualizações baratos ... e você quer ser seguro para uso simultâneo. experimentar:

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

Desta forma, você tem uma operação para atualizações e um máximo de 3 operações para inserções. Então, se você está geralmente atualizando esta é uma opção barata seguro.

Também gostaria de ter muito cuidado para não usar qualquer coisa que não é seguro para uso simultâneo. Sua realmente fácil de obter violações de chave primárias ou linhas duplicadas na produção.

Respondeu 21/09/2008 em 23:05
fonte usuário

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