Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Dowiedz się, czy ograniczenie CHECK jest na poziomie kolumny czy na poziomie tabeli w programie SQL Server (przykłady T-SQL)

Kiedy tworzysz CHECK ograniczenia w SQL Server, możesz nawet nie myśleć o tym, czy jest to ograniczenie na poziomie tabeli, czy na poziomie kolumny.

CHECK na poziomie tabeli ograniczenie dotyczy tabeli, podczas gdy ograniczenie na poziomie kolumny dotyczy określonej kolumny. Z CHECK na poziomie tabeli ograniczenie, jest to wiersz, który jest sprawdzany podczas sprawdzania danych. Za pomocą kolumny CHECK na poziomie kolumny ograniczenie, zaznaczona jest konkretna kolumna.

Generalnie będziesz wiedzieć, czy ograniczenie, które tworzysz, jest ograniczeniem na poziomie tabeli, czy na poziomie kolumny, dzięki podanej przez Ciebie definicji. Jeśli w wyrażeniu jest sprawdzana tylko jedna kolumna, będzie to ograniczenie na poziomie kolumny. W przeciwnym razie będzie to ograniczenie na poziomie tabeli.

Ale skąd wiesz, czy istniejące ograniczenia są na poziomie kolumny czy tabeli?

Możesz uruchomić dowolny z poniższych przykładów kodu, aby określić, czy istniejące ograniczenia są na poziomie kolumny czy tabeli. Pobierają one wszystkie CHECK ograniczenia dla bieżącej bazy danych, ale zawsze możesz użyć WHERE klauzulę, aby zawęzić ją do konkretnego ograniczenia.

Przykład 1 – zapytanie podstawowe

Oto proste zapytanie, które zwraca podstawowe informacje o wszystkich CHECK ograniczenia w bieżącej bazie danych.

Tutaj pytam o sys.check_constraints widok systemowy (który zwraca wiersz dla każdego obiektu będącego CHECK ograniczenie, z sys.objects.type = 'C' ). Zwracam tylko cztery kolumny (ale możesz zwrócić tyle kolumn, ile chcesz).

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

Wynik:

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

Najszybszym sposobem określenia, które ograniczenia są ograniczeniami na poziomie tabeli, jest szukanie zera ( 0 ) w parent_column_id kolumna. Wszystko, co ma zero, to CHECK na poziomie tabeli ograniczenie. Wartość niezerowa wskazuje, że jest to CHECK na poziomie kolumny ograniczenie zdefiniowane w kolumnie o określonej wartości identyfikatora.

W tym przykładzie występują trzy ograniczenia na poziomie kolumny i jedno ograniczenie na poziomie tabeli.

Zwróć uwagę, że istnieją dwa ograniczenia z tym samym parent_column_id (3) jednak te dwa ograniczenia pochodzą z różnych tabel. 3 odnosi się do trzeciej kolumny odpowiednich tabel.

Jak wspomniano, jeśli chcesz uzyskać informacje tylko o określonym ograniczeniu, użyj WHERE klauzula:

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

Wynik:

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

Przykład 2 – Ulepsz zapytanie

Możemy poprawić poprzedni przykład, zwracając nazwę kolumny nadrzędnej zamiast samego jej identyfikatora. Oczywiście zwróci to nazwę kolumny tylko dla ograniczeń na poziomie kolumny. W przypadku ograniczeń na poziomie tabeli zostanie zwrócone NULL.

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;

Wynik:

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

Przykład 3 – Dalsze ulepszenia

Dostosujmy zapytanie jeszcze bardziej:

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;

Wynik:

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

Tak więc mam teraz zwracany tekst „Poziom kolumny” lub „Poziom tabeli”, w zależności od tego, który to jest.

Używam również ISNULL() funkcja zmieniająca dowolne wartości NULL na „(nie dotyczy)”.

Dodałem również is_disabled kolumny do listy, na wypadek gdyby którekolwiek z ograniczeń zostało wyłączone. Zawsze możesz potraktować tę kolumnę tak samo jak parent_column_id kolumnę i przedstawić „Tak” lub „Nie” lub „Włączone” lub „Wyłączone” lub podobne.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Podzapytanie programu SQL Server zwróciło więcej niż 1 wartość. Nie jest to dozwolone, gdy podzapytanie następuje po =, !=, <, <=,>,>=

  2. Jak ustawić sortowanie kolumny w SQL Server (T-SQL)

  3. 🆕 Pierwsze spojrzenie na SQL Server 2022 — 5 najlepszych nowych funkcji (dodatkowe 5 funkcji)

  4. 3 sposoby na wyświetlenie listy wszystkich procedur składowanych w bazie danych SQL Server

  5. SUBSTRING Polecenie w SQL:elementarz