web-dev-qa-db-fra.com

Je souhaite utiliser l'instruction CASE pour mettre à jour certains enregistrements dans SQL Server 2005

UPDATE dbo.TestStudents  
SET LASTNAME = 
( CASE  
WHEN (LASTNAME = 'AAA') THEN 'BBB' 
WHEN (LASTNAME = 'CCC') THEN 'DDD' 
WHEN (LASTNAME = 'EEE') THEN 'FFF' 
ELSE  (LASTNAME)
END )

L'instruction fonctionne à cette fin, mais la condition else analyse tous les enregistrements de la table. Est-il possible de laisser les lignes non affectées telles quelles?

150
user2236361

Ajouter une clause WHERE

UPDATE dbo.TestStudents  
SET     LASTNAME =  CASE  
                        WHEN LASTNAME = 'AAA' THEN 'BBB' 
                        WHEN LASTNAME = 'CCC' THEN 'DDD' 
                        WHEN LASTNAME = 'EEE' THEN 'FFF' 
                        ELSE LASTNAME
                    END 
WHERE   LASTNAME IN ('AAA', 'CCC', 'EEE')
272
John Woo

C'est aussi une utilisation alternative de case-when ...

UPDATE [dbo].[JobTemplates]
SET [CycleId] = 
    CASE [Id]
        WHEN 1376 THEN 44   --ACE1 FX1
        WHEN 1385 THEN 44   --ACE1 FX2
        WHEN 1574 THEN 43   --ACE1 ELEM1
        WHEN 1576 THEN 43   --ACE1 ELEM2
        WHEN 1581 THEN 41   --ACE1 FS1
        WHEN 1585 THEN 42   --ACE1 HS1
        WHEN 1588 THEN 43   --ACE1 RS1
        WHEN 1589 THEN 44   --ACE1 RM1
        WHEN 1590 THEN 43   --ACE1 ELEM3
        WHEN 1591 THEN 43   --ACE1 ELEM4
        WHEN 1595 THEN 44   --ACE1 SSTn     
        ELSE 0  
     END
WHERE
    [Id] IN (1376,1385,1574,1576,1581,1585,1588,1589,1590,1591,1595)

J'aime l'utilisation des tables temporaires dans les cas où les valeurs en double ne sont pas autorisées et que votre mise à jour peut les créer. Par exemple:

SELECT
     [Id]
    ,[QueueId]
    ,[BaseDimensionId]
    ,[ElastomerTypeId]
    ,CASE [CycleId]
        WHEN  29 THEN 44
        WHEN  30 THEN 43
        WHEN  31 THEN 43
        WHEN 101 THEN 41
        WHEN 102 THEN 43
        WHEN 116 THEN 42
        WHEN 120 THEN 44
        WHEN 127 THEN 44
        WHEN 129 THEN 44
        ELSE    0
     END                AS [CycleId]
INTO
    ##ACE1_PQPANominals_1
FROM 
    [dbo].[ProductionQueueProcessAutoclaveNominals]
WHERE
    [QueueId] = 3
ORDER BY 
    [BaseDimensionId], [ElastomerTypeId], [Id];
---- (403 row(s) affected)

UPDATE [dbo].[ProductionQueueProcessAutoclaveNominals]
SET 
    [CycleId] = X.[CycleId]
FROM
    [dbo].[ProductionQueueProcessAutoclaveNominals]
INNER JOIN
(
    SELECT  
        MIN([Id]) AS [Id],[QueueId],[BaseDimensionId],[ElastomerTypeId],[CycleId] 
    FROM 
        ##ACE1_PQPANominals_1
    GROUP BY    
        [QueueId],[BaseDimensionId],[ElastomerTypeId],[CycleId] 
) AS X
ON
    [dbo].[ProductionQueueProcessAutoclaveNominals].[Id] = X.[Id];
----(375 row(s) affected)
16
David

Si vous ne voulez pas répéter la liste deux fois (comme indiqué dans la réponse de @J W), placez les mises à jour dans une variable de table et utilisez un JOIN dans le UPDATE:

declare @ToDo table (FromName varchar(10), ToName varchar(10))
insert into @ToDo(FromName,ToName) values
 ('AAA','BBB'),
 ('CCC','DDD'),
 ('EEE','FFF')

update ts set LastName = ToName
from dbo.TestStudents ts
       inner join
     @ToDo t
       on
         ts.LastName = t.FromName
5