UNIQUE és több NULL

(This article has an English version…)
Ha szeretnénk biztosítani azt, hogy egy oszlop értékei mind egyeidek legyenek, akkor használhatjuk a UNIQUE kulcsszót (akár constraint, akár index formában), hogy ezt kierőszakoljuk. Ez eddig szép és jó, de mi a helyzet a NULL értékekkel? Egy NULL-t simán be tudunk szúrni (ez ugye a nagy különbség a UNIQUE és a PRIMARY KEY között, utóbbi nem enged semmilyen NULL-t), de mi van, ha sok NULL-t akarok bepakolni? Pl. tároljuk az ügyfelek pénzügyi azonosítóját a különféle ki- és befizetések azonosítására, de vannak ügyfeleink, akikkel nincs ilyen pénzügyi kapcsolatunk. A klasszikus ANSI SQL szerint lehet több NULL egy UNIQUE oszlopban, hiszen NULL <> NULL a definíció szerint. A Microsoft által használt megközelítés meg azt mondja, hogy ha megtalálom az értéket a táblában, akkor az nem lehet egyedi. Lehet vitatkozni a nézőpontokon (azt hiszem, meglepő módon a DB2 is az utóbbit használja), mindenesetre változtatni rajta nemigen lehet. Vannak mindenféle érdekes kerülőutak, de mindenesetre, ez elég bosszantó lehet. Annak, aki nem használ SQL Server 2008-at. A SQL 2008-ban bevezetett filtered index nevű feature lehetőséget biztosít arra, hogy ne az egész táblára, csak annak egy részére készítsük el az indexünket. A szintaktika roppant egyszerű:
Hogyan segít ez rajtunk? Hát, egyszerűen: adjuk hozzá azt a feltételt, hogy csak a nem NULL oszlopokra akarunk UNIQUE indexet készíteni. Rövid példa:

CREATE TABLE tempdb.dbo.t1 (col1 int)
CREATE UNIQUE INDEX IX_t1_col1 on tempdb.dbo.t1 (col1)
WHERE col1 IS NOT NULL
-- dobjunk be par sort...
INSERT INTO tempdb.dbo.t1 VALUES (1),(2),(NULL)
--ez bukta
INSERT INTO tempdb.dbo.t1 VALUES (1)
--ez nem bukta
INSERT INTO tempdb.dbo.t1 VALUES (NULL)

És tessék, máris Oracle-kompatibilis UNIQUE-or kaptunk. Jó, mi? :)

Leave a comment