Implementação do SQL Server 2005 do MySQL REPLACE INTO?
-
08-06-2019 - |
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?
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.