2017-01-11 5 views
1

Je gardais un ensemble de valeurs (1 enregistrement) à une table de cette façon:SQL multiples INSERT ou UPDATE

UPDATE Table SET ... 
IF @@ROWCOUNT = 0 INSERT INTO Table ... 

Cela a bien fonctionné, mais maintenant je dois ajouter des enregistrements plus indépendants en même temps , donc j'ai essayé quelque chose comme:

UPDATE Table SET ... 
IF @@ROWCOUNT = 0 INSERT INTO Table ... 

UPDATE Table SET ... 
IF @@ROWCOUNT < 2 INSERT INTO Table ... 

UPDATE Table SET ... 
IF @@ROWCOUNT < 3 INSERT INTO Table ... 

UPDATE Table SET ... 
IF @@ROWCOUNT < 4 INSERT INTO Table ... 

... pour le garder en 1 transaction. Cependant, à partir de la 2ème déclaration, il ajoute des lignes, même si la ligne particulière est déjà en place - apparemment @@ROWCOUNT ne compte pas INSERT lignes ées, ou je mal compris le concept d'une autre manière ...

Je me demande s'il y a une manière possible pour résoudre cela dans la requête SQL. Dans ce cas particulier, devrait être OK pour supposer que tous les enregistrements dépendent de l'existence de la première, mais il n'est pas fiable à 100% et je voudrais savoir une meilleure solution, si elle existe.

EDIT - solution:

Cela peut ne pas être possible dans toutes les applications (être au courant, que les mises à jour particulières ne sont pas vérifiées séparément), mais dans mon cas, il apears bien fonctionner et doivent aussi être compatibles avec les données, car l'ensemble des données mises à jour/insérées est intégral.

UPDATE Table SET ... 
UPDATE Table SET ... 
UPDATE Table SET ... 
UPDATE Table SET ... 
IF @@ROWCOUNT = 0 
BEGIN 
    INSERT INTO Table ... 
    INSERT INTO Table ... 
    INSERT INTO Table ... 
    INSERT INTO Table ... 
END 
+0

Vous devriez être en mesure d'en faire une sous-requête ... quelque chose comme 'insérer dans la casse de la table lorsque row_count = 0 alors ... quand row_count = 1 puis ... end comme stuff de (select count (1) as row_count de la table) a; '? –

+0

Oh wait ... est '@@ ROWCOUNT' le nombre de lignes affectées par le premier' UPDATE'? Mon tsql est assez rouillé. –

+0

Hmm, pardonnez mon manque de connaissances, mais une sous-requête fonctionnera-t-elle vraiment (avec de nouvelles données) avant que la transaction soit terminée? –

Répondre

2

UPDATE TABLE ..... 
 
IF(condition) 
 
BEGIN 
 
/* 
 
do insert here 
 
*/ 
 
END 
 
IF(condition) 
 
BEGIN 
 
/* 
 
do insert here 
 
*/ 
 
END

Source: SQL Tutorials

+0

Cela semble vraiment, vraiment propre et simple. Je vais le tester et marquer comme une réponse lors des tests. –

3

Une solution un peu plus propre à vous problème peut être utiliser:

DECLARE @Reasons TABLE (Name NVARCHAR(50) PRIMARY KEY, ReasonType NVARCHAR(50)) 

INSERT INTO @Reasons (Name, ReasonType) VALUES (N'Review', N'Old Reason') 

SELECT * FROM @Reasons 

MERGE INTO @Reasons AS Target 
USING (VALUES 
('Recommendation','Other'), 
('Review', 'Marketing'), 
('Internet', 'Promotion') 
) 
     AS Source (NewName, NewReasonType) 
ON Target.Name = Source.NewName 
WHEN MATCHED THEN 
UPDATE SET ReasonType = Source.NewReasonType 
WHEN NOT MATCHED BY TARGET THEN 
INSERT (Name, ReasonType) VALUES (NewName, NewReasonType) ; 

SELECT * FROM @Reasons 

vous recevrez alors tout ou rien , sans toutes les conditions. Voir https://msdn.microsoft.com/en-us/library/bb510625.aspx détails sur l'instruction de fusion.

+1

Je ne vois pas une instruction UPDATE ici ...? Si des données existent, elles doivent être mises à jour, uniquement si un nouvel enregistrement n'est pas créé. –

+0

Ah, j'ai raté cette partie. Je posterai une solution mise à jour. –

+0

C'est une bien meilleure réponse que la réponse acceptée. –