Question

MySQL a ceci incroyablement utile mais propriétaire REPLACE INTO Commande SQL.

Cela peut-il facilement être émulé dans SQL Server 2005 ?

Démarrer une nouvelle transaction, effectuer une Select() et puis soit UPDATE ou INSERT et COMMIT C'est toujours un peu pénible, surtout quand on le fait dans l'application et donc toujours en gardant 2 versions de la déclaration.

Je me demande s'il existe un moyen facile et universel Comment implémenter une telle fonction dans SQL Server 2005 ?

Était-ce utile?

La solution

C'est quelque chose qui m'ennuie avec MSSQL (diatribe sur mon blog).Je souhaite que MSSQL soit pris en charge upsert.

Le code de @ Dillie-O est un bon moyen dans les anciennes versions de SQL (+1 vote), mais il s'agit toujours essentiellement de deux opérations d'E/S (la exists et puis le update ou insert)

Il existe une méthode légèrement meilleure ce post, essentiellement:

--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 le réduit à une opération d'E/S s'il s'agit d'une mise à jour, ou à deux s'il s'agit d'une insertion.

MS SQL2008 présente merge à partir de la norme 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, ... )

Maintenant, ce n'est en réalité qu'une seule opération d'E/S, mais un code horrible :-(

Autres conseils

La fonctionnalité que vous recherchez est traditionnellement appelée UPSERT.Savoir au moins comment ça s'appelle pourrait vous aider à trouver ce que vous cherchez.

Je ne pense pas que SQL Server 2005 dispose d'un excellent moyen de procéder.2008 introduit l'instruction MERGE qui peut être utilisée pour accomplir cela, comme indiqué dans : 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 était disponible dans la version bêta de 2005, mais ils l'ont supprimé dans la version finale.

Ce que fait l'upsert/merge est quelque chose qui a pour 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 pourra faire bouger les choses.

j'ai écrit un article de blog sur ce problème.

L'essentiel est que si vous voulez des mises à jour bon marché...et vous voulez être en sécurité pour une utilisation simultanée.essayer:

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 disposez d'une opération pour les mises à jour et d'un maximum de 3 opérations pour les insertions.donc, si vous effectuez généralement une mise à jour, il s’agit d’une option sûre et bon marché.

Je ferais également très attention à ne pas utiliser quoi que ce soit qui soit dangereux pour une utilisation simultanée.Il est très facile d'obtenir des violations de clé primaire ou des lignes en double en production.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top