T-SQL: utilizzo di un CASE in un'istruzione UPDATE per aggiornare determinate colonne a seconda di una condizione


108

Mi chiedo se questo sia possibile. Voglio aggiornare la colonna x se una condizione è vera, altrimenti la colonna y verrebbe aggiornata

UPDATE table SET
     (CASE (CONDITION) WHEN TRUE THEN columnx
                       ELSE columny
      END)
= 25

Ho cercato ovunque, provato alcune cose e non sono in grado di trovare una soluzione. Penso che non sia possibile, ma ho pensato di chiedere qui e vedere se qualcuno l'ha fatto prima. Grazie in anticipo.


Supponendo che tutti siano nello stesso tavolo, sì. Puoi sempre eseguirlo in una transazione e rollback in caso di errore, per vedere di persona.
Pony OMG

Non sono sicuro di cosa intendi. Ho provato a mettere un condizionale per la colonna, ma non funziona. Funziona per un'istruzione select, ma non per un'istruzione di aggiornamento. (Select (case (condition) when true then columnx else columny end) from myTable ... the update non funziona, and I can see why. There doesn ' Non mi sembra un modo per farlo funzionare.
pqsk

Risposte:


188

Non è possibile utilizzare una condizione per modificare la struttura della query, ma solo i dati coinvolti. Potresti farlo:

update table set
    columnx = (case when condition then 25 else columnx end),
    columny = (case when condition then columny else 25 end)

Semanticamente è lo stesso, ma tieni presente che entrambe le colonne verranno sempre aggiornate . Questo probabilmente non causerà alcun problema, ma se hai un volume di transazioni elevato, potrebbe causare problemi di concorrenza.

L'unico modo per fare in modo specifico ciò che stai chiedendo è utilizzare SQL dinamico. Tuttavia, questo è qualcosa da cui ti incoraggio a stare lontano. La soluzione sopra sarà quasi certamente sufficiente per ciò che stai cercando.


Sono d'accordo sull'SQL dinamico. Quindi i miei dati saranno influenzati? Voglio dire, non voglio che sia cambiato per determinate condizioni. Quindi reinserirà solo ciò che è già presente? La quantità di accessi al database potrebbe non essere così grave.
pqsk

@pqsk: questo non dovrebbe influire sui tuoi dati, dovrebbe semplicemente reinserire ciò che è già presente per qualsiasi colonna non dovrebbe essere interessata.
Adam Robinson

Grazie. Vado con questo. Così semplice, anche un uomo delle caverne può farlo. haha.
pqsk

1
@AdamRobinson Sono passati 1,5 anni conosci qualche modo più efficiente per aggiornare solo una colonna

@Somebodyisintrouble: l'unico modo per aggiornare una colonna è utilizzare una query diversa.
Adam Robinson,

23
UPDATE  table
SET     columnx = CASE WHEN condition THEN 25 ELSE columnx END,
        columny = CASE WHEN condition THEN columny ELSE 25 END

1
Hai appena copiato la risposta di Adam o è stata presa da qualche altra parte? haha. L'ho appena notato.
pqsk

1
@pqsk: le nostre risposte erano a circa 1 minuto di distanza, quindi immagino di aver fatto clic su Invia un po 'più velocemente;)
Adam Robinson

23
@pqsk: sì, ho appena copiato la risposta di Adam, 23pochi secondi prima che la pubblicasse. Sono un copypaster veloce!
Quassnoi

2
@pqsk: se metti il ​​cursore su * min ago, ti mostrerà l'ora esatta in cui è stato pubblicato.
Quassnoi

2
Per essere onesti, anche se entrambi sono la stessa cosa: se Adam fosse uscito dopo il tuo, ha elaborato ancora un po '. Ecco perché ho contrassegnato la sua come risposta. Grazie comunque.
pqsk

4

inserisci qui la descrizione dell'immagine

Voglio cambiare o aggiornare il mio ContactNo a 8018070999 dove c'è 8018070777 usando l'istruzione Case

update [Contacts] set contactNo=(case 
when contactNo=8018070777 then 8018070999
else
contactNo
end)

inserisci qui la descrizione dell'immagine


1
per questo perché non utilizzare questa query AGGIORNAMENTO [Contatti] SET contactNo = 8018070999 WHERE contactNo = 8018070777
NewGuy

4

So che questa è una domanda molto vecchia, ma ha funzionato per me:

UPDATE TABLE SET FIELD1 =
CASE 
WHEN FIELD1 = Condition1 THEN 'Result1'
WHEN FIELD1 = Condition2 THEN 'Result2'
WHEN FIELD1 = Condition3 THEN 'Result3'
END;

Saluti


1

So che questa è una domanda molto vecchia e il problema è contrassegnato come risolto. Tuttavia, se qualcuno con un caso come il mio in cui la tabella ha un trigger per la registrazione dei dati sugli eventi di aggiornamento, ciò causerà problemi. Entrambe le colonne riceveranno l'aggiornamento e il log renderà inutili le voci. Il modo in cui l'ho fatto

IF (CONDITION) IS TRUE
BEGIN
    UPDATE table SET columnx = 25
END
ELSE
BEGIN
    UPDATE table SET columny = 25
END

Ora questo ha un altro vantaggio che non ha scritture inutili sul tavolo come le soluzioni di cui sopra.


questo è un buon punto e una buona alternativa! Non sto più lavorando al codice originale che porta a questo thread, ma è sempre bene avere soluzioni diverse e penso che questa sia una buona soluzione
pqsk

-1

Credo che tu possa omettere l'aggiornamento delle colonne "non desiderate" modificando le altre risposte come segue:
update table set columnx = (case when condition1 then 25 end), columny = (case when condition2 then 25 end)

A quanto ho capito, questo si aggiornerà solo quando la condizione sarà soddisfatta.

Dopo aver letto tutti i commenti, questo è il più efficiente:
Update table set ColumnX = 25 where Condition1 Update table set ColumnY = 25 where Condition1

Tabella di esempio:
CREATE TABLE [dbo].[tblTest]( [ColX] [int] NULL, [ColY] [int] NULL, [ColConditional] [bit] NULL, [id] [int] IDENTITY(1,1) NOT NULL ) ON [PRIMARY]
Dati di esempio:
Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 0) Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 0) Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 1) Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 1) Insert into tblTest (ColX, ColY, ColConditional) values (1, null, null) Insert into tblTest (ColX, ColY, ColConditional) values (2, null, null) Insert into tblTest (ColX, ColY, ColConditional) values (null, 1, null) Insert into tblTest (ColX, ColY, ColConditional) values (null, 2, null)

ora presumo che sia possibile scrivere un condizionale che gestisce i valori nulli. Per il mio esempio, presumo che tu abbia scritto un tale condizionale che restituisce True, False o Null. Se hai bisogno di aiuto con questo, fammelo sapere e farò del mio meglio.

Ora l'esecuzione di queste due righe di codice cambia infatti X in 25 se e solo se ColConditional è True (1) e Y in 25 se e solo se ColConditional è False (0)

Update tblTest set ColX = 25 where ColConditional = 1 Update tblTest set ColY = 25 where ColConditional = 0

PS Il caso nullo non è mai stato menzionato nella domanda originale o in eventuali aggiornamenti alla domanda, ma come puoi vedere, questa risposta molto semplice li gestisce comunque.


1
Questo in realtà non funziona. Per uno, se la colonna consente valori nulli, quando la condizione non viene soddisfatta viene assegnato un valore nullo. Nel caso in cui i valori nulli non siano consentiti, l'aggiornamento non riuscirà. La tua query finale "efficiente" non è sql non valido, almeno in TSQL. Lo hai testato su un motore specifico e ha funzionato per te?
pqsk

L'ho testato su SQL Server 2005 e funziona perfettamente come mostrato. Vorrei sicuramente sapere perché è stato votato verso il basso e un esempio che mostra il valore NULL che viene aggiornato, perché nel mio test sopra, il valore null non viene aggiornato. Ho sempre pensato che la risposta più semplice sia la migliore e se ho a che fare con un database con milioni di record sono sicuro che non voglio aggiornare le righe non necessarie.
John Greiner
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.