sql >> Database teknologi >  >> RDS >> Sqlserver

Find ud af, om en CHECK-begrænsning er på kolonneniveau eller tabelniveau i SQL Server (T-SQL-eksempler)

Når du opretter en CHECK begrænsning i SQL Server, tænker du måske ikke engang over, om det er en begrænsning på tabelniveau eller en begrænsning på kolonneniveau.

En CHECK på tabelniveau begrænsning gælder for tabellen, hvorimod en begrænsning på kolonneniveau gælder for en specifik kolonne. Med en CHECK på tabelniveau begrænsning, det er rækken, der kontrolleres, når den tjekker dataene. Med en CHECK på kolonneniveau begrænsning, det er den specifikke kolonne, der er markeret.

Generelt vil du vide, om den begrænsning, du opretter, er en begrænsning på tabelniveau eller kolonneniveau ifølge den definition, du giver den. Hvis kun én kolonne er markeret i udtrykket, vil det være en begrænsning på kolonneniveau. Ellers vil det være en begrænsning på tabelniveau.

Men hvordan ved du, om dine eksisterende begrænsninger er på kolonneniveau eller tabelniveau?

Du kan køre et hvilket som helst af kodeeksemplerne nedenfor for at bestemme, om dine eksisterende begrænsninger er på kolonneniveau eller tabelniveau. Disse henter alle CHECK begrænsninger for den aktuelle database, men du kan altid bruge en WHERE klausul for at indsnævre det til en specifik begrænsning.

Eksempel 1 – Grundlæggende forespørgsel

Her er en simpel forespørgsel, der returnerer grundlæggende oplysninger om alle CHECK begrænsninger i den aktuelle database.

Her forespørger jeg sys.check_constraints systemvisning (som returnerer en række for hvert objekt, der er en CHECK begrænsning med sys.objects.type = 'C' ). Jeg returnerer kun fire kolonner (men du er velkommen til at returnere så mange kolonner, du vil).

SELECT 
  Name,
  OBJECT_NAME(parent_object_id) AS 'Table',
  parent_column_id,
  Definition
FROM sys.check_constraints;

Resultat:

+-----------------+----------------+--------------------+----------------------------------------+
| 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')          |
+-----------------+----------------+--------------------+----------------------------------------+

Den hurtigste måde at bestemme, hvilke begrænsninger der er begrænsninger på tabelniveau, er at kigge efter nullet ( 0 ) i parent_column_id kolonne. Alt med et nul er et CHECK på tabelniveau begrænsning. En værdi, der ikke er nul, angiver, at det er en CHECK på kolonneniveau begrænsning defineret i kolonnen med den angivne ID-værdi.

Så i dette eksempel er der tre begrænsninger på kolonneniveau og en begrænsning på tabelniveau.

Bemærk, at der er to begrænsninger med det samme parent_column_id (3), men disse to begrænsninger er fra forskellige tabeller. De 3 refererer til den tredje kolonne i deres respektive tabeller.

Som nævnt, hvis du kun ønsker information om en specifik begrænsning, skal du bruge en WHERE klausul:

SELECT 
  Name,
  OBJECT_NAME(parent_object_id) AS 'Table',
  parent_column_id,
  Definition
FROM sys.check_constraints
WHERE name = 'chkPrice';

Resultat:

+----------+----------------+--------------------+---------------+
| Name     | Table          | parent_column_id   | Definition    |
|----------+----------------+--------------------+---------------|
| chkPrice | ConstraintTest | 2                  | ([Price]>(0)) |
+----------+----------------+--------------------+---------------+

Eksempel 2 – Forbedre forespørgslen

Vi kan forbedre det forrige eksempel ved at returnere det overordnede kolonnenavn i stedet for kun dets ID. Dette vil naturligvis kun returnere kolonnenavnet for begrænsninger på kolonneniveau. For begrænsninger på tabelniveau vil NULL blive returneret.

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;

Resultat:

+-----------------+----------------+----------+----------------------------------------+
| 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')          |
+-----------------+----------------+----------+----------------------------------------+

Eksempel 3 – Yderligere forbedringer

Lad os justere forespørgslen noget mere:

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;

Resultat:

+-----------------+-------------+----------------+----------------+----------+----------------------------------------+
| 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')          |
+-----------------+-------------+----------------+----------------+----------+----------------------------------------+

Så jeg får nu teksten "Kolonne-niveau" eller "Tabel-niveau" tilbage, afhængigt af hvilken det er.

Jeg bruger også ISNULL() funktion til at omdanne eventuelle NULL-værdier til "(n/a)".

Og jeg har også tilføjet is_disabled kolonne til listen, bare hvis nogen af ​​begrænsningerne er blevet deaktiveret. Du kan altid give denne kolonne samme behandling som parent_column_id kolonne og præsentere "Ja" eller "Nej" eller "Aktiveret" eller "Deaktiveret" eller lignende.


  1. Oracle-tal til C# decimal

  2. Et kig på Oracle Group-by Bug

  3. Hierarkiske forespørgsler i SQL Server 2005

  4. PostgreSQL-tendenser:Mest populære cloud-udbydere, sprog, VACUUM, forespørgselsstyringsstrategier og implementeringstyper i virksomheder