[MS SQL] Update alleen indien huidige waarde NIET null is

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Urk
  • Registratie: Maart 2000
  • Laatst online: 12-05 23:58
Ik heb een SQL Query (MS SQL 2017 DB) waarin ik een aantal velden wil updaten, maar alleen wanneer de huidige kolom al een waarde heeft. Indien die NULL is moet de waarde NULL blijven.
Uiteraard in Google gegooid en verschillend opties geprobeerd maar dat werkt allemaal niet.
Ook dien ik meerdere velden te updaten in 1 query:

Het volgende al geprobeerd:
SQL:
1
UPDATE registraties SET a_naam = CASE WHEN a_naam IS NOT NULL THEN 'Nieuwe waarde' WHERE ID > 1;


SQL:
1
UPDATE registraties SET a_naam = IsNull('Nieuwe waarde', a_naam), a_adres = IsNull('Nieuwe waarde', a_adres) WHERE ID > 1;


Kan dit uberhaupt? En kan dit met een eenvoudige/korte syntax? _/-\o_

Beste antwoord (via Urk op 30-08-2021 02:06)


  • vandeGerrit
  • Registratie: Januari 2009
  • Laatst online: 23-04 22:08

vandeGerrit

Well, this can't be right

Een kortere notatie zou je kunnen bereiken met IIF.

code:
1
   a_naam = IIF(a_naam is null, null, 'Nieuwe waarde')

[ Voor 17% gewijzigd door vandeGerrit op 21-07-2021 22:25 ]

Alle reacties


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Nu online
Welke foutmeldingen krijg? Is dat op syntax of functioneel niveau? Oftewel. Doet het niet wat je wil, of wil MSSQL je query sowieso niet uitvoeren?

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • +10 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Laatst online: 16:01

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

Waarom zet je 't niet gewoon in je WHERE clause erbij :?

WHERE x > y AND z IS NOT NULL

[ Voor 35% gewijzigd door RobIII op 21-07-2021 11:45 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • +1 Henk 'm!

  • ocwil
  • Registratie: Mei 2007
  • Laatst online: 13-05 16:58
Uhmm waarom filter je de a_naam IS NOT NULL niet in de where clause?

[ Voor 3% gewijzigd door ocwil op 21-07-2021 11:45 ]

~ Portal 2 maps: linkje ~ LoL (EUW): Ocwil ~


Acties:
  • 0 Henk 'm!

  • thof
  • Registratie: Oktober 2008
  • Nu online

thof

FP ProMod
Wat de anderen ook al zeggen, opnemen in je where clause.
Je krijgt dan zoiets:

SQL:
1
2
3
UPDATE registraties 
   SET a_naam = 'Nieuwe waarde' 
 WHERE ID > 1 AND a_naam IS NOT NULL;


Alternatief kan nog zijn de waarde altijd wel zetten, maar dan dus vullen met de waarde die het al had. Bijvoorbeeld vanuit een stuk software en/of ORM.

[ Voor 9% gewijzigd door thof op 21-07-2021 11:47 ]

Server 1: Intel N305 | 48GB RAM | 5*4TB NVME | 4x 2.5GbE
Server 2: Intel N5105 | 64GB RAM | 1TB NVME | 4x 2.5GbE
Server 3: Intel Xeon E5-2670 | 128GB RAM | 512+750GB SATA SSD | 6x10TB HDD | 6x 1GbE [Buiten gebruik]


Acties:
  • 0 Henk 'm!

  • Urk
  • Registratie: Maart 2000
  • Laatst online: 12-05 23:58
thof schreef op woensdag 21 juli 2021 @ 11:46:
Wat de anderen ook al zeggen, opnemen in je where clause.
Je krijgt dan zoiets:

SQL:
1
2
3
UPDATE registraties 
   SET a_naam = 'Nieuwe waarde' 
 WHERE ID > 1 AND a_naam IS NOT NULL;
Nee, dat kan niet. Ik doe een update van zo'n 10 kolommen. Die kunnen in de huidige situatie gevuld maar ook NULL zijn. Alleen de gevulde waarden moeten worden geupdatet.

Acties:
  • 0 Henk 'm!

  • bwerg
  • Registratie: Januari 2009
  • Niet online

bwerg

Internettrol

Urk schreef op woensdag 21 juli 2021 @ 12:14:
[...]


Nee, dat kan niet. Ik doe een update van zo'n 10 kolommen. Die kunnen in de huidige situatie gevuld maar ook NULL zijn. Alleen de gevulde waarden moeten worden geupdatet.
En waarom kan dat niet? Dat is toch precies wat een "WHERE ... IS NOT NULL" doet?

edit: ah, je hebt tien kolommen en die moeten afzonderlijk op null-gecontroleerd en eventueel gevuld worden?

[ Voor 12% gewijzigd door bwerg op 21-07-2021 12:20 ]

Heeft geen speciale krachten en is daar erg boos over.


Acties:
  • 0 Henk 'm!

  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 16:46
Je hebt de argumenten in IsNull verkeerd om.

Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Nu online
bwerg schreef op woensdag 21 juli 2021 @ 12:18:
[...]
edit: ah, je hebt tien kolommen en die moeten afzonderlijk op null-gecontroleerd en eventueel gevuld worden?
Dat dus :)

Het zou op beide manieren moeten kunnen, daarom vroeg ik eerder al waar het mis gaat? Krijg je syntax fouten of doet het niet wat je wil. We kunnen het wel voorkauwen, maar daar leer je niks van. Het antwoord op deze vraag helpt ons je weer in de juiste richting te duwen.

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Laatst online: 16:01

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

Urk schreef op woensdag 21 juli 2021 @ 12:14:
Nee, dat kan niet. Ik doe een update van zo'n 10 kolommen. Die kunnen in de huidige situatie gevuld maar ook NULL zijn. Alleen de gevulde waarden moeten worden geupdatet.
Dat was wel handig als je dat wat duidelijker had aangegeven in je topicstart. Maar wat werkt er dan niet aan de eerste query uit je topicstart? Zoals @CurlyMo al vroeg - welke foutmelding krijg je? Want ik denk dat je een END mist maar het principe van je query zou moeten werken :?

[ Voor 9% gewijzigd door RobIII op 21-07-2021 13:40 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Urk
  • Registratie: Maart 2000
  • Laatst online: 12-05 23:58
bwerg schreef op woensdag 21 juli 2021 @ 12:18:
[...]
edit: ah, je hebt tien kolommen en die moeten afzonderlijk op null-gecontroleerd en eventueel gevuld worden?
;) haha, klopt helemaal inderdaad!

Acties:
  • 0 Henk 'm!

  • Urk
  • Registratie: Maart 2000
  • Laatst online: 12-05 23:58
CurlyMo schreef op woensdag 21 juli 2021 @ 12:26:
[...]
Het zou op beide manieren moeten kunnen, daarom vroeg ik eerder al waar het mis gaat? Krijg je syntax fouten of doet het niet wat je wil. We kunnen het wel voorkauwen, maar daar leer je niks van. Het antwoord op deze vraag helpt ons je weer in de juiste richting te duwen.
Nee hoor, krijg geen foutmelding echter wordt een kolom ook geupdatet als de waarde al leeg was. En dat is niet de bedoeling.
Dus al ik deze query uitvoer:
SQL:
1
UPDATE registraties SET a_naam = IsNull('Nieuwe waarde', a_naam), a_adres = IsNull('Nieuwe waarde', a_adres) WHERE ID > 1;

Dan worden beide waarden altijd geupdatet. Ook al was het veld daarvoor NULL...

Acties:
  • 0 Henk 'm!

  • Urk
  • Registratie: Maart 2000
  • Laatst online: 12-05 23:58
RobIII schreef op woensdag 21 juli 2021 @ 13:39:
[...]

Dat was wel handig als je dat wat duidelijker had aangegeven in je topicstart. Maar wat werkt er dan niet aan de eerste query uit je topicstart? Zoals @CurlyMo al vroeg - welke foutmelding krijg je? Want ik denk dat je een END mist maar het principe van je query zou moeten werken :?
Sorry, was misschien niet duidelijk genoeg. Als ik het zelf nogmaals lees is het voor mij duidelijk maar voor jullie wellicht niet...
Als ik de query:
SQL:
1
UPDATE registraties SET a_naam = CASE WHEN a_naam IS NOT NULL THEN 'Nieuwe waarde' WHERE ID > 1;

uitvoer krijg ik geen foutmelding maar wel als ik in deze query 2 velden wil updaten. Bij:

SQL:
1
UPDATE registraties SET a_naam = CASE WHEN a_naam IS NOT NULL THEN 'Nieuwe waarde', a_adres = CASE WHEN a_adres IS NOT NULL THEN 'Nieuwe waarde' WHERE ID > 1;


krijg ik wel een syntax fout. Maar misschien klopt mijn syntax idd niet. Werkt ook niet als ik CASE WHEN THEN waarde tussen haakjes zet.... 8)7

Acties:
  • 0 Henk 'm!

  • vandeGerrit
  • Registratie: Januari 2009
  • Laatst online: 23-04 22:08

vandeGerrit

Well, this can't be right

RobIII schreef op woensdag 21 juli 2021 @ 13:39:
Want ik denk dat je een END mist maar het principe van je query zou moeten werken :?
Ik denk dat als je het antwoord van @RobIII nog een keer leest, je het probleem wel ziet.

edit:
Reactie aangepast op feedback van @CurlyMo

[ Voor 85% gewijzigd door vandeGerrit op 21-07-2021 15:50 ]


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Nu online
Urk schreef op woensdag 21 juli 2021 @ 14:52:
[...]
Als ik het zelf nogmaals lees is het voor mij duidelijk maar voor jullie wellicht niet...
Ik snapte je direct :) Maar ja, als ik de enige bent heb je daar weinig aan.

[ Voor 49% gewijzigd door CurlyMo op 21-07-2021 16:05 ]

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Is het hier niet makkelijker om gewoon van de COALESCE syntax gebruik te maken ( Uiteindelijk doet het hetzelfde, maar IMHO is het een stuk beter leesbaar

dus
SQL:
1
2
3
4
UPDATE Tabel
SET Value1 = COALESCE(Value1, @NewValue1 ),
Value2 = COALESCE(Value2, @NewValue2 )
//ETC

[ Voor 16% gewijzigd door Woy op 21-07-2021 15:09 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • +1 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Nu online
Woy schreef op woensdag 21 juli 2021 @ 15:08:
Is het hier niet makkelijker om gewoon van de COALESCE syntax gebruik te maken ( Uiteindelijk doet het hetzelfde, maar IMHO is het een stuk beter leesbaar
Dat dacht ik ook, maar TS wil het omgekeerde :)

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
CurlyMo schreef op woensdag 21 juli 2021 @ 15:11:
[...]

Dat dacht ik ook, maar TS wil het omgekeerde :)
Ik zag het ook net, maar je was te snel voordat ik mijn post aan kon passen :+

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • +1 Henk 'm!

  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 15:47

The Eagle

I wear my sunglasses at night

Ik ben met name benieuwd waar de requirement om dit met 1 query teh doen vandaan komt. Het zal wel kunnen, maar hij wordt met ieder extra te updaten veld complexer.
Als het in een scriptje mag met 10 update statements achter elkaar ben je er zo volgens mij.

Having said that: je zou in je WHERE een inline view kunnne gebruiken om je initiele selectie kleiner te maken.
voorbeeldje:
SQL:
1
2
3
UPDATE registraties set a_naam = 'Nieuwe waarde', a_adres = 'Nieuwe waarde'
where x in
(select 'x' from registraties where a_naam is not null and a_adress is not null)

Uiteraard kun je met die inline view wpelen voor de juiste filters en combinaties. Let wel: je kunt veld 1 tm 10 allemaal NULL hebben, maar ook veld 1,2,3 en 10 null en de rest wel gevuld, en iedere combi die er tussen zit. Dat met 1 query oplossen kan, maar dat zijn wel een hoop combinaties om te programmeren ;)

Wat zou helpen is als je beter kunt pinpointen wat wanneer voorkomt en in welke combinatie(s), indien mogelijk.

Mag het wel in een scriptje, maak dan 10 losse update statements a la:
SQL:
1
UPDATE registraties set a_naam = 'Nieuwe waarde' where a_naam is not null


Overigens kun je een case statement zoals je het eerst gebruikte ook afvangen met een tussentabel waarin je de nieuwe en oude waardes laadt voor de diverse veklden. Dan wordt het zoiets:
SQL:
1
2
3
UPDATE registraties 
set a_naam = (select nw_value from tussentabel where old_value = a_naam and col_type="a_naam" )
where a_naam is not null

Definitie van tussentabel is dan (col_type, old_value, nw_value)
met als vulling bijvoorbeeld ('a_naam', 'Jansen', Pietersen')

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


Acties:
  • 0 Henk 'm!

  • mbe81
  • Registratie: Juni 2008
  • Laatst online: 12:56
Je kan dit doen met een ‘CASE WHEN’ in je update. Je krijgt dan zoiets als:

code:
1
2
3
UPDATE registraties 
SET a_naam = CASE WHEN a_naam is null THEN null ELSE nw_value END
WHERE etc…


Zie ook: https://docs.microsoft.co...sql?view=sql-server-ver15

Edit: Ik zie dat je iets soortgelijks in je eerste statement probeert maar daar mist de END. Dat zal dus een foutmelding hebben gegeven?

[ Voor 23% gewijzigd door mbe81 op 21-07-2021 19:50 ]


Acties:
  • 0 Henk 'm!

  • thof
  • Registratie: Oktober 2008
  • Nu online

thof

FP ProMod
Urk schreef op woensdag 21 juli 2021 @ 12:14:
[...]


Nee, dat kan niet. Ik doe een update van zo'n 10 kolommen. Die kunnen in de huidige situatie gevuld maar ook NULL zijn. Alleen de gevulde waarden moeten worden geupdatet.
Even semantisch dan, want SQL is ook niet helaamaal mijn skill en geen IDE bij de hand. Volgens mij kan dat wat jij wil nog steeds met een ISNULL check.

SQL:
1
2
3
4
UPDATE registraties 
   SET a_naam = ISNULL('Nieuwe waarde', a_naam),
       b_naam = ISNULL('Nieuwe andere waarde', b_naam)
 WHERE ID > 1;


a_naam zal in de DB standaard NULL zijn, dus zodra je deze voor het eerst probeert te updaten, dan zal hij altijd een nieuwe waarde tenzij de nieuwe waarde NULL is, dan blijft deze a_naam (die dus al null was). Een probleempje met deze opzet, je kan een veld niet naar NULL zetten.

Nog even los van waarom je dit misschien wil, want ik ben de constructie die je wilt bereiken in de praktijk (10+ jaar development) nog niet tegen gekomen.

[ Voor 3% gewijzigd door thof op 21-07-2021 21:34 ]

Server 1: Intel N305 | 48GB RAM | 5*4TB NVME | 4x 2.5GbE
Server 2: Intel N5105 | 64GB RAM | 1TB NVME | 4x 2.5GbE
Server 3: Intel Xeon E5-2670 | 128GB RAM | 512+750GB SATA SSD | 6x10TB HDD | 6x 1GbE [Buiten gebruik]


Acties:
  • 0 Henk 'm!

  • mbe81
  • Registratie: Juni 2008
  • Laatst online: 12:56
thof schreef op woensdag 21 juli 2021 @ 21:33:
Even semantisch dan, want SQL is ook niet helaamaal mijn skill en geen IDE bij de hand. Volgens mij kan dat wat jij wil nog steeds met een ISNULL check.
TS wil het omgekeerde: als de bestaande waarde NULL is, dan moet de waarde in de tabel NULL blijven, anders mag deze ge-update worden.

Acties:
  • 0 Henk 'm!

  • thof
  • Registratie: Oktober 2008
  • Nu online

thof

FP ProMod
mbe81 schreef op woensdag 21 juli 2021 @ 22:10:
[...]


TS wil het omgekeerde: als de bestaande waarde NULL is, dan moet de waarde in de tabel NULL blijven, anders mag deze ge-update worden.
Ligt er denk ik een beetje aan hoe je het implementeert in een geheel, als je eerst een select gedaan hebt en die data in-memory hebt en daarna een update runt, zal 'Nieuwe waarde' NULL zijn waardoor null behouden blijft. Maar mooi en betrouwbaar is anders. Dan zou ik inderdaad naar een CASE WHEN gaan kijken. Nog liever zou ik het helemaal niet met SQL oplossen maar in een eventuele applicatie zelf.

Server 1: Intel N305 | 48GB RAM | 5*4TB NVME | 4x 2.5GbE
Server 2: Intel N5105 | 64GB RAM | 1TB NVME | 4x 2.5GbE
Server 3: Intel Xeon E5-2670 | 128GB RAM | 512+750GB SATA SSD | 6x10TB HDD | 6x 1GbE [Buiten gebruik]


Acties:
  • Beste antwoord
  • +3 Henk 'm!

  • vandeGerrit
  • Registratie: Januari 2009
  • Laatst online: 23-04 22:08

vandeGerrit

Well, this can't be right

Een kortere notatie zou je kunnen bereiken met IIF.

code:
1
   a_naam = IIF(a_naam is null, null, 'Nieuwe waarde')

[ Voor 17% gewijzigd door vandeGerrit op 21-07-2021 22:25 ]


Acties:
  • 0 Henk 'm!

  • Rotterdammertje
  • Registratie: Juni 2002
  • Laatst online: 28-03-2023
Urk schreef op woensdag 21 juli 2021 @ 14:52:
[...]

Bij:

SQL:
1
UPDATE registraties SET a_naam = CASE WHEN a_naam IS NOT NULL THEN 'Nieuwe waarde', a_adres = CASE WHEN a_adres IS NOT NULL THEN 'Nieuwe waarde' WHERE ID > 1;


krijg ik wel een syntax fout.
Het is voor volgende keren wel zo handig om dan ook te vertellen *welke* syntax fout je krijgt. ;)

main = putStr (q ++ show q); q = "main = putStr (q ++ show q); q = "


Acties:
  • 0 Henk 'm!

  • mbe81
  • Registratie: Juni 2008
  • Laatst online: 12:56
Rotterdammertje schreef op donderdag 22 juli 2021 @ 11:12:
[...]


Het is voor volgende keren wel zo handig om dan ook te vertellen *welke* syntax fout je krijgt. ;)
In dit stukje mist ook twee keer de END bij de CASE.

Acties:
  • 0 Henk 'm!

  • Urk
  • Registratie: Maart 2000
  • Laatst online: 12-05 23:58
vandeGerrit schreef op woensdag 21 juli 2021 @ 22:24:
Een kortere notatie zou je kunnen bereiken met IIF.

code:
1
   a_naam = IIF(a_naam is null, null, 'Nieuwe waarde')
Sorry, reactie duurde even maar dit werkte perfect! Prima oplossing dus _/-\o_
Pagina: 1