Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Tìm hiểu xem Ràng buộc KIỂM TRA là Cấp cột hay Cấp bảng trong SQL Server (Ví dụ T-SQL)

Khi bạn tạo CHECK trong SQL Server, bạn thậm chí có thể không nghĩ đó là ràng buộc cấp bảng hay ràng buộc cấp cột.

CHECK cấp bảng ràng buộc áp dụng cho bảng, trong khi ràng buộc cấp cột áp dụng cho một cột cụ thể. Với CHECK cấp bảng ràng buộc, đó là hàng được kiểm tra khi kiểm tra dữ liệu. Với CHECK cấp cột ràng buộc, đó là cột cụ thể được kiểm tra.

Nói chung, bạn sẽ biết liệu ràng buộc bạn đang tạo có phải là ràng buộc cấp bảng hay cấp cột hay không theo định nghĩa mà bạn đưa ra. Nếu chỉ một cột đang được kiểm tra trong biểu thức, nó sẽ là một ràng buộc cấp cột. Nếu không, nó sẽ là một ràng buộc cấp bảng.

Nhưng làm cách nào để biết liệu các ràng buộc hiện tại của bạn là cấp cột hay cấp bảng?

Bạn có thể chạy bất kỳ ví dụ mã nào bên dưới để xác định xem các ràng buộc hiện tại của bạn là cấp cột hay cấp bảng. Những thứ này truy xuất tất cả CHECK các ràng buộc đối với cơ sở dữ liệu hiện tại, nhưng bạn luôn có thể sử dụng WHERE để thu hẹp nó thành một ràng buộc cụ thể.

Ví dụ 1 - Truy vấn cơ bản

Đây là một truy vấn đơn giản trả về thông tin cơ bản về tất cả CHECK các ràng buộc trong cơ sở dữ liệu hiện tại.

Tại đây, tôi truy vấn sys.check_constraints chế độ xem hệ thống (trả về một hàng cho mỗi đối tượng là CHECK ràng buộc, với sys.objects.type = 'C' ). Tôi chỉ trả về bốn cột (nhưng bạn có thể trả lại bao nhiêu cột tùy thích).

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

Kết quả:

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

Cách nhanh nhất để xác định ràng buộc nào là ràng buộc cấp bảng là tìm giá trị 0 ( 0 ) trong parent_column_id cột. Bất kỳ thứ gì có số 0 đều là CHECK cấp bảng hạn chế. Giá trị khác 0 cho biết rằng đó là CHECK cấp cột ràng buộc được xác định trên cột với giá trị ID được chỉ định.

Vì vậy, trong ví dụ này có ba ràng buộc cấp cột và một ràng buộc cấp bảng.

Lưu ý rằng có hai ràng buộc với cùng một parent_column_id (3), tuy nhiên, hai ràng buộc này là từ các bảng khác nhau. Số 3 đề cập đến cột thứ ba trong các bảng tương ứng của chúng.

Như đã đề cập, nếu bạn chỉ muốn thông tin về một ràng buộc cụ thể, hãy sử dụng WHERE mệnh đề:

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

Kết quả:

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

Ví dụ 2 - Cải thiện Truy vấn

Chúng ta có thể cải thiện ví dụ trước bằng cách trả về tên cột cha thay vì chỉ ID của nó. Tất nhiên, điều này sẽ trả về tên cột chỉ cho các ràng buộc cấp cột. Đối với các ràng buộc cấp bảng, NULL sẽ được trả về.

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;

Kết quả:

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

Ví dụ 3 - Cải tiến Hơn nữa

Hãy điều chỉnh thêm một số truy vấn:

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;

Kết quả:

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

Vì vậy, bây giờ tôi có văn bản "Cấp cột" hoặc "Cấp bảng" được trả về, tùy thuộc vào đó là văn bản nào.

Tôi cũng sử dụng ISNULL() hàm để biến bất kỳ giá trị NULL nào thành “(n / a)”.

Và tôi cũng đã thêm is_disabled vào danh sách, đề phòng trường hợp bất kỳ ràng buộc nào đã bị vô hiệu hóa. Bạn luôn có thể cung cấp cho cột này cùng cách xử lý với parent_column_id và hiển thị “Có” hoặc “Không” hoặc “Đã bật” hoặc “Đã tắt” hoặc tương tự.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ví dụ về câu lệnh hợp nhất đơn giản trong SQL Server

  2. Không thể kết nối với localDB trong VS2012 - Đã xảy ra lỗi liên quan đến mạng hoặc trường hợp cụ thể khi thiết lập kết nối với SQL Server ...

  3. Chạy gói SSIS bằng dtexec

  4. Làm cách nào để tạo và truy vấn các máy chủ cơ sở dữ liệu được liên kết trong SQL Server?

  5. Làm mới bảng máy chủ SQL với ít gián đoạn hơn bằng cách sử dụng chuyển đổi phân vùng