89 votes

Implémentation SQL Server 2005 de MySQL REPLACE INTO?

MySQL a cette incroyablement utile encore properitary REPLACE INTO la Commande SQL.

Je me demande: Peut facilement être imité dans SQL Server 2005?

Le démarrage d'une nouvelle Opération, en faisant l' Select() puis UPDATE ou INSERT et COMMIT est toujours un peu d'une douleur, surtout quand le faire dans l'application et, par conséquent, en gardant toujours 2 versions de la déclaration.

Je me demande si il ya un moyen facile et universelle façon de mettre en œuvre une telle fonction dans SQL Server 2005?

62voto

Keith Points 46288

C'est quelque chose qui me dérange à propos de MSSQL (coup de gueule sur mon blog). Je souhaite MSSQL pris en charge upsert.

@Dillie-O code est un bon moyen dans les anciennes versions SQL (+1 voix), mais il s'agit essentiellement de deux opérations d'e / s ( exists , puis l' update ou insert)

Il y a un peu de mieux sur ce post, en gros:

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

Cela réduit-il à une opérations d'e / s si c'est une mise à jour, ou deux si un insert.

MS Sql2008 introduit merge SQL:2003 standard:

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

Maintenant, il est vraiment juste une opération e / s, mais c'est affreux code :-(

20voto

Karl Seguin Points 10566

La fonctionnalité que vous recherchez est traditionnellement appelé un UPSERT. Au moins savoir de quoi il s'appelle peut vous aider à trouver ce que vous cherchez.

Je ne pense pas que SQL Server 2005 est une grande manière de le faire. 2008 introduit l'instruction MERGE qui peuvent être utilisés pour y parvenir: http://www.databasejournal.com/features/mssql/article.php/3739131 ou http://blogs.conchango.com/davidportas/archive/2007/11/14/SQL-Server-2008-MERGE.aspx

Fusion était disponible dans la version bêta de 2005, mais ils l'ont enlevé dans la version finale.

17voto

Dillie-O Points 16780

Ce que l'upsert / merge fait est quelque chose à l'effet de ...

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

J'espère donc que la combinaison de ces articles et de ce pseudo-code peut faire avancer les choses.

10voto

Sam Saffron Points 56236

J'ai écrit un billet de blog à propos de ce problème.

La ligne de fond est que si vous voulez pas cher les mises à jour ... et vous voulez être en sécurité pour l'utilisation simultanée. essayez:

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

De cette façon, vous avez 1 de l'opération pour les mises à jour et un maximum de 3 opérations pour les insertions. donc, si vous êtes généralement la mise à jour c'est sûr option la moins coûteuse.

Je serais également très attention à ne pas utiliser tout ce qui est dangereux pour l'utilisation simultanée. Son vraiment facile pour obtenir des violations de clé primaire ou de dupliquer des lignes de production.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X