Wanneer u een CHECK
. aanmaakt beperking in SQL Server, denk je er misschien niet eens over na of het een beperking op tabelniveau of een beperking op kolomniveau is.
Een CHECK
op tabelniveau beperking is van toepassing op de tabel, terwijl een beperking op kolomniveau van toepassing is op een specifieke kolom. Met een CHECK
op tabelniveau beperking, het is de rij die wordt gecontroleerd wanneer deze de gegevens controleert. Met een CHECK
op kolomniveau beperking, het is de specifieke kolom die is aangevinkt.
Over het algemeen weet u aan de hand van de definitie die u eraan geeft of de beperking die u maakt, een beperking op tabel- of kolomniveau is. Als er slechts één kolom wordt gecontroleerd in de expressie, is dit een beperking op kolomniveau. Anders is het een beperking op tabelniveau.
Maar hoe weet u of uw bestaande beperkingen op kolom- of tabelniveau zijn?
U kunt elk van de onderstaande codevoorbeelden uitvoeren om te bepalen of uw bestaande beperkingen op kolomniveau of op tabelniveau zijn. Deze halen alle CHECK
beperkingen voor de huidige database, maar u kunt altijd een WHERE
. gebruiken clausule om het te beperken tot een specifieke beperking.
Voorbeeld 1 – Basisquery
Hier is een eenvoudige zoekopdracht die basisinformatie retourneert over alle CHECK
beperkingen in de huidige database.
Hier vraag ik de sys.check_constraints
systeemweergave (die een rij retourneert voor elk object dat een CHECK
is beperking, met sys.objects.type = 'C'
). Ik retourneer slechts vier kolommen (maar voel je vrij om zoveel kolommen terug te geven als je wilt).
SELECT Name, OBJECT_NAME(parent_object_id) AS 'Table', parent_column_id, Definition FROM sys.check_constraints;
Resultaat:
+-----------------+----------------+--------------------+----------------------------------------+ | Name | Table | parent_column_id | Definition | |-----------------+----------------+--------------------+----------------------------------------| | chkPrice | ConstraintTest | 2 | ([Price]>(0)) | | chkValidEndDate | ConstraintTest | 0 | ([EndDate]>=[StartDate]) | | chkTeamSize | ConstraintTest | 3 | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | Occupation | 3 | ([JobTitle]<>'Digital Nomad') | +-----------------+----------------+--------------------+----------------------------------------+
De snelste manier om te bepalen welke beperkingen beperkingen op tabelniveau zijn, is door te zoeken naar de nul (
0
) in de
parent_column_id
kolom. Alles met een nul is een CHECK
op tabelniveau beperking. Een waarde die niet nul is, geeft aan dat het een CHECK
op kolomniveau is beperking gedefinieerd op de kolom met de gespecificeerde ID-waarde.
In dit voorbeeld zijn er dus drie beperkingen op kolomniveau en één beperking op tabelniveau.
Merk op dat er twee beperkingen zijn met dezelfde parent_column_id (3) deze twee beperkingen komen echter uit verschillende tabellen. De 3 verwijst naar de derde kolom van hun respectievelijke tabellen.
Zoals gezegd, als je alleen informatie wilt over een specifieke beperking, gebruik dan een WHERE
clausule:
SELECT Name, OBJECT_NAME(parent_object_id) AS 'Table', parent_column_id, Definition FROM sys.check_constraints WHERE name = 'chkPrice';
Resultaat:
+----------+----------------+--------------------+---------------+ | Name | Table | parent_column_id | Definition | |----------+----------------+--------------------+---------------| | chkPrice | ConstraintTest | 2 | ([Price]>(0)) | +----------+----------------+--------------------+---------------+
Voorbeeld 2 – Verbeter de zoekopdracht
We kunnen het vorige voorbeeld verbeteren door de naam van de bovenliggende kolom te retourneren in plaats van alleen de ID. Dit retourneert natuurlijk alleen de kolomnaam voor beperkingen op kolomniveau. Voor beperkingen op tabelniveau wordt NULL geretourneerd.
SELECT cc.name AS 'Constraint', o.name AS 'Table', ac.name AS 'Column', cc.Definition AS 'Constraint Definition' FROM sys.check_constraints cc LEFT OUTER JOIN sys.objects o ON cc.parent_object_id = o.object_id LEFT OUTER JOIN sys.all_columns ac ON cc.parent_column_id = ac.column_id AND cc.parent_object_id = ac.object_id;
Resultaat:
+-----------------+----------------+----------+----------------------------------------+ | Constraint | Table | Column | Constraint Definition | |-----------------+----------------+----------+----------------------------------------| | chkPrice | ConstraintTest | Price | ([Price]>(0)) | | chkValidEndDate | ConstraintTest | NULL | ([EndDate]>=[StartDate]) | | chkTeamSize | ConstraintTest | TeamSize | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | Occupation | JobTitle | ([JobTitle]<>'Digital Nomad') | +-----------------+----------------+----------+----------------------------------------+
Voorbeeld 3 – Verdere verbeteringen
Laten we de vraag nog wat aanpassen:
SELECT cc.name AS 'Constraint', cc.is_disabled AS 'Disabled?', CASE WHEN cc.parent_column_id = 0 THEN 'Table-level' ELSE 'Column-level' END AS 'Table/Column', o.name AS 'Table', ISNULL(ac.name, '(n/a)') AS 'Column', cc.Definition AS 'Constraint Definition' FROM sys.check_constraints cc LEFT OUTER JOIN sys.objects o ON cc.parent_object_id = o.object_id LEFT OUTER JOIN sys.all_columns ac ON cc.parent_column_id = ac.column_id AND cc.parent_object_id = ac.object_id;
Resultaat:
+-----------------+-------------+----------------+----------------+----------+----------------------------------------+ | Constraint | Disabled? | Table/Column | Table | Column | Constraint Definition | |-----------------+-------------+----------------+----------------+----------+----------------------------------------| | chkPrice | 0 | Column-level | ConstraintTest | Price | ([Price]>(0)) | | chkValidEndDate | 0 | Table-level | ConstraintTest | (n/a) | ([EndDate]>=[StartDate]) | | chkTeamSize | 0 | Column-level | ConstraintTest | TeamSize | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | 0 | Column-level | Occupation | JobTitle | ([JobTitle]<>'Digital Nomad') | +-----------------+-------------+----------------+----------------+----------+----------------------------------------+
Dus ik heb nu de tekst "Kolomniveau" of "Tabelniveau" die wordt geretourneerd, afhankelijk van welke het is.
Ik gebruik ook de ISNULL()
functie om NULL-waarden om te zetten in "(n/a)".
En ik heb ook de is_disabled . toegevoegd kolom naar de lijst, voor het geval een van de beperkingen is uitgeschakeld. U kunt deze kolom altijd dezelfde behandeling geven als de parent_column_id kolom en presenteer "Ja" of "Nee" of "Ingeschakeld" of "Uitgeschakeld" of iets dergelijks.