Inloggen
 
 
 
 
    
Behalve in SQL2005
Location: BlogsHenri Koppen - Developer    
Posted by: Henri Koppen 15-2-2008 9:52
Af en toe kom ik functionaliteit tegen waar ik wellicht wel over gelezen heb, maar die niet zijn blijven hangen, behalve -ofwel EXCEPT in SQL 2005- is zo'n functionaliteit.


Niet alleen kun je EXCEPT gebruiken om verschillen in data tussen gelijke tabellen te tonen. Je kunt ook antwoord krijgen op de vraag: Welke taken hebben geen geschiedenis.

Zie hier een voorbeeld:

SELECT t.guid
FROM tblTaken t
EXCEPT
SELECT his.TaakId
FROM tblTakenGeschiedenis his


Normaal gesproken zou ik deze query op deze manier:

SELECT * FROM tblTaken t WHERE NOT EXISTS (SELECT * FROM tblTakenGeschiedenis his WHERE his.TaakId = t.guid)

Of op deze manier:

SELECT * FROM tblTaken t LEFT JOIN tblTakenGeschiedenis his ON his.TaakId = t.guid WHERE his.TaakId IS NULL

schrijven. Beide voorbeelden hebben wel een net ander resultaat, maar het gaat om de constructie.

Ik schrijf het op zodat een volgende keer waarin ik een soortgelijke ingewikkeldere situatie tegenkom, EXCEPT misschien de juiste tool is.
Een sterk voorbeeld is denk ik in een trigger. Ik maak wel eens triggers die af gaan als 1 van een aantal velden veranderd is. Daar moet ik dan hele WHERE clausules schrijven zoals AND ( ISNULL (i.BeginDatum, GETDATE()-1) = ISNULL (d.BeginDatum, GETDATE()-1) OR d.EindDatum IS NULL) maar met EXCEPT gaat dat een stuk gemakkelijker.
EXCEPT ziet bijvoorbeeld NULL en NULL als gelijk! en dat is zeer handig.

Lees voor meer informatie:

http://msdn2.microsoft.com/nl-nl/library/ms188055(en-us).aspx 

Hier een voorbeeld van hoe een trigger een stuk makkelijker lees (en schrijft!)


-- OUD
-- Schrijf taakgeschiedenis bij wijzigen van Deadline, Uitvoerder, UitvoerderRol
INSERT INTO tblTakenGeschiedenis (TaakId, UitvoerderId, UitvoerderRolId, StartDatum, Deadline, Afgehandeld, IngevoerdDoor)
SELECT i.guid, i.UitvoerderId, i.UitvoerderRolId, i.StartDatum, i.Deadline, i.Afgehandeld, CASE WHEN i.GewijzigdDoor IS NULL THEN i.IngevoerdDoor ELSE i.GewijzigdDoor END
FROM INSERTED i
LEFT JOIN DELETED d ON d.guid = i.guid
 WHERE (
   (i.UitvoerderId <> d.UitvoerderId OR (d.UitvoerderId IS NULL AND i.UitvoerderId IS NOT NULL) OR (d.UitvoerderId IS NOT NULL AND i.UitvoerderId IS NULL))
   OR (i.UitvoerderRolId <> d.UitvoerderRolId OR (d.UitvoerderRolId IS NULL AND i.UitvoerderRolId IS NOT NULL) OR (d.UitvoerderRolId IS NOT NULL AND i.UitvoerderRolId IS NULL))
   OR (i.StartDatum <> d.StartDatum OR (d.StartDatum IS NULL AND i.StartDatum IS NOT NULL) OR (d.StartDatum IS NOT NULL AND i.StartDatum IS NULL))
   OR (i.Deadline <> d.Deadline OR (d.Deadline IS NULL AND i.Deadline IS NOT NULL) OR (d.Deadline IS NOT NULL AND i.Deadline IS NULL))
   OR (i.Afgehandeld <> d.Afgehandeld OR (d.Afgehandeld IS NULL AND i.Afgehandeld IS NOT NULL) OR (d.Afgehandeld IS NOT NULL AND i.Afgehandeld IS NULL))
   )


-- NIEUW
-- Schrijf taakgeschiedenis bij wijzigen van Deadline, Uitvoerder, UitvoerderRol
INSERT INTO tblTakenGeschiedenis (TaakId, UitvoerderId, UitvoerderRolId, StartDatum, Deadline, Afgehandeld, IngevoerdDoor)
SELECT i.guid, i.UitvoerderId, i.UitvoerderRolId, i.StartDatum, i.Deadline, i.Afgehandeld, CASE WHEN i.GewijzigdDoor IS NULL THEN i.IngevoerdDoor ELSE i.GewijzigdDoor END AS [IngevoerdDoor]
FROM INSERTED i
EXCEPT
SELECT d.guid, d.UitvoerderId, d.UitvoerderRolId, d.StartDatum, d.Deadline, d.Afgehandeld, CASE WHEN d.GewijzigdDoor IS NULL THEN d.IngevoerdDoor ELSE d.GewijzigdDoor END
FROM DELETED d

 


 

Copyright ©2008 Henri Koppen
Permalink |  Trackback
  
 
Weblogs
    
Archief
    
Zoeken
    
 
 
 
 
Copyright 2006-2009 by Arcencus
Privacy Statement | Terms Of Use