Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Разберете дали ограничението CHECK е на ниво колона или на ниво таблица в SQL Server (примери за T-SQL)

Когато създадете CHECK ограничение в SQL Server, може дори да не мислите дали това е ограничение на ниво таблица или ограничение на ниво колона.

CHECK на ниво таблица ограничението се прилага към таблицата, докато ограничение на ниво колона се прилага за конкретна колона. С CHECK на ниво таблица ограничение, това е редът, който се проверява, когато проверява данните. С CHECK на ниво колона ограничение, това е конкретната колона, която се проверява.

Като цяло ще знаете дали ограничението, което създавате, е ограничение на ниво таблица или колона според определението, което му давате. Ако в израза се проверява само една колона, това ще бъде ограничение на ниво колона. В противен случай това ще бъде ограничение на ниво таблица.

Но как да разберете дали съществуващите ви ограничения са на ниво колона или на ниво таблица?

Можете да изпълните някой от примерите за код по-долу, за да определите дали вашите съществуващи ограничения са на ниво колона или на ниво таблица. Те извличат всички CHECK ограничения за текущата база данни, но винаги можете да използвате WHERE клауза, за да я стесните до конкретно ограничение.

Пример 1 – Основна заявка

Ето една проста заявка, която връща основна информация за всички CHECK ограничения в текущата база данни.

Тук правя заявка за sys.check_constraints системен изглед (който връща ред за всеки обект, който е CHECK ограничение, с sys.objects.type = 'C' ). Връщам само четири колони (но не се колебайте да върнете толкова колони, колкото искате).

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

Резултат:

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

Най-бързият начин да определите кои ограничения са ограничения на ниво таблица е да потърсите нулата ( 0 ) в id_parent_column_id колона. Всичко с нула е CHECK на ниво таблица ограничение. Ненулева стойност показва, че това е CHECK на ниво колона ограничение, дефинирано за колоната с посочената стойност на ID.

Така че в този пример има три ограничения на ниво колона и едно ограничение на ниво таблица.

Имайте предвид, че има две ограничения със същия parent_column_id (3), обаче, тези две ограничения са от различни таблици. 3 се отнася до третата колона на съответните им таблици.

Както споменахме, ако искате информация само за конкретно ограничение, използвайте WHERE клауза:

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

Резултат:

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

Пример 2 – Подобрете заявката

Можем да подобрим предишния пример, като върнем името на родителската колона вместо само нейния идентификатор. Разбира се, това ще върне името на колоната само за ограниченията на ниво колона. За ограничения на ниво таблица ще бъде върнато 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;

Резултат:

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

Пример 3 – Допълнителни подобрения

Нека настроим още малко заявката:

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;

Резултат:

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

Така че сега се връща текстът „на ниво колона“ или „на ниво таблица“, в зависимост от това кой е.

Използвам и ISNULL() функция за превръщане на всички NULL стойности в „(n/a)“.

И също така добавих is_disabled колона в списъка, само в случай, че някое от ограниченията е деактивирано. Винаги можете да дадете на тази колона същото третиране като parent_column_id колона и представете „Да“ или „Не“, или „Активирано“ или „Деактивирано“ или подобно.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да увеличите допустимия размер на прикачените файлове при изпращане на имейл в SQL Server (T-SQL)

  2. 5 начина да коригирате грешката „Деление на нула“ в SQL Server (Msg 8134)

  3. Как да разбера какво заключва масите ми?

  4. Какво е DTU в Azure SQL база данни и как да разберем колко ни трябва

  5. Регистърът на транзакциите на SQL Server, част 2:Архитектура на журнала