sql >> Database >  >> RDS >> Sqlserver

Zoek uit of een CHECK-beperking op kolomniveau of op tabelniveau is in SQL Server (T-SQL-voorbeelden)

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.


  1. Goed nieuws voor Standard Edition-klanten in SQL Server 2014

  2. Hoe drop Unique Constraint-scripts in SQL Server-database te genereren - SQL Server / TSQL-zelfstudie, deel 99

  3. Twee rijen samenvoegen tot één terwijl u null-waarden vervangt

  4. RAWTONHEX() Functie in Oracle