Pergunta

O MySQL tem esse recurso incrivelmente útil, mas proprietário REPLACE INTO Comando SQL.

Isso pode ser facilmente emulado no SQL Server 2005?

Iniciando uma nova Transação, fazendo uma Select() e então também UPDATE ou INSERT e COMMIT é sempre um pouco chato, principalmente quando se faz isso no aplicativo e por isso sempre mantém 2 versões do extrato.

Eu me pergunto se existe uma maneira fácil e universal maneira de implementar tal função no SQL Server 2005?

Foi útil?

Solução

Isso é algo que me irrita no MSSQL (desabafo no meu blog).Desejo suporte para MSSQL upsert.

O código de @Dillie-O é uma boa maneira em versões SQL mais antigas (+1 voto), mas ainda é basicamente duas operações IO (o exists e então o update ou insert)

Há uma maneira um pouco melhor esta postagem, 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', ... )

Isso reduz a uma operação IO se for uma atualização ou duas se for uma inserção.

MS Sql2008 apresenta merge do 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 um código horrível :-(

Outras dicas

A funcionalidade que você procura é tradicionalmente chamada de UPSERT.Pelo menos saber como se chama pode ajudá-lo a encontrar o que procura.

Não acho que o SQL Server 2005 tenha ótimas maneiras de fazer isso.2008 introduz a instrução MERGE que pode ser usada para fazer isso, conforme mostrado em: http://www.databasejournal.com/features/mssql/article.php/3739131 ou http://blogs.conchango.com/davidportas/archive/2007/11/14/SQL-Server-2008-MERGE.aspx

Merge estava disponível na versão beta de 2005, mas foi removido na versão final.

O que o upsert/merge está fazendo é algo no sentido de ...

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

Esperamos que a combinação desses artigos e esse pseudocódigo possa fazer as coisas andarem.

Eu escrevi um postagem no blog sobre esse assunto.

O resultado final é que se você quiser atualizações baratas ...e você deseja estar seguro para uso simultâneo.tentar:

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 1 operação para atualizações e no máximo 3 operações para inserções.então, se você está atualizando geralmente, esta é uma opção segura e barata.

Eu também tomaria muito cuidado para não usar nada que não fosse seguro para uso simultâneo.É realmente fácil obter violações de chave primária ou linhas duplicadas na produção.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top