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

Cách tìm tất cả vi phạm ràng buộc trong cơ sở dữ liệu máy chủ SQL

Bạn có thể chạy DBCC CHECKCONSTRAINTS lệnh console để trả về danh sách tất cả các vi phạm ràng buộc trong cơ sở dữ liệu SQL Server.

Lệnh này kiểm tra tính toàn vẹn của một ràng buộc được chỉ định hoặc tất cả các ràng buộc trên một bảng được chỉ định trong cơ sở dữ liệu hiện tại. Nó trả về bất kỳ khóa ngoại nào và CHECK vi phạm ràng buộc mà nó tìm thấy.

Bạn có thể sử dụng ALL_CONSTRAINTS tùy chọn để kiểm tra cả các ràng buộc đã bật và đã tắt. Nếu bạn bỏ qua điều này, thì chỉ các ràng buộc đã bật được trả về (trừ khi bạn chỉ định rõ ràng một ràng buộc để kiểm tra, trong trường hợp đó, nó sẽ được trả về bất kể được bật hay tắt).

Ví dụ 1 - Ràng buộc KIỂM TRA Vi phạm

Tôi đã chạy ví dụ này dựa trên cơ sở dữ liệu có chứa một số CHECK vi phạm ràng buộc.

USE Test;
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;

Kết quả:

+------------------------+-------------------+---------------------------------------------------------+
| Table                  | Constraint        | Where                                                   |
|------------------------+-------------------+---------------------------------------------------------|
| [dbo].[Occupation]     | [chkJobTitle]     | [JobTitle] = 'Digital Nomad'                            |
| [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' |
| [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' |
+------------------------+-------------------+---------------------------------------------------------+

Điều này cho thấy rằng tôi có ba vi phạm ràng buộc trong cơ sở dữ liệu của mình.

Giải thích các cột

Ba cột trả về thông tin sau:

Bảng
Tên bảng chứa vi phạm ràng buộc.
Ràng buộc
Tên của ràng buộc bị vi phạm.
Ở đâu
Gán giá trị cột xác định hàng hoặc các hàng vi phạm ràng buộc. Giá trị trong cột này có thể được sử dụng trong WHERE mệnh đề của một SELECT truy vấn câu lệnh cho các hàng vi phạm ràng buộc.

Do đó, nhờ cột thứ ba, giờ đây tôi có thể tìm (và cập nhật) tất cả dữ liệu không hợp lệ.

Tìm dữ liệu không hợp lệ

Vì vậy, nếu chúng ta nhìn vào hàng đầu tiên từ DBCC CHECKCONSTRAINTS của tôi kết quả, chúng tôi thấy rằng chúng tôi có thể tìm thấy dữ liệu vi phạm bằng cách sử dụng [JobTitle] = 'Digital Nomad' trong một WHERE mệnh đề.

Như thế này:

SELECT *
FROM [dbo].[Occupation]
WHERE [JobTitle] = 'Digital Nomad';

Kết quả:

+----------------+---------------+
| OccupationId   | JobTitle      |
|----------------+---------------|
| 7              | Digital Nomad |
+----------------+---------------+

Định nghĩa Ràng buộc

Hãy xem định nghĩa thực tế cho chkJobTitle ràng buộc:

SELECT Definition 
FROM sys.check_constraints
WHERE name = 'chkJobTitle';

Kết quả:

+-------------------------------+
| Definition                    |
|-------------------------------|
| ([JobTitle]<>'Digital Nomad') |
+-------------------------------+

Ràng buộc này nói rằng giá trị của JobTitle cột phải không Digital Nomad , vậy mà một người du mục kỹ thuật số vẫn vào được cơ sở dữ liệu của tôi!

Cập nhật dữ liệu vi phạm

Bạn có thể cập nhật dữ liệu vi phạm, xóa hoặc để nguyên.

Trong ví dụ này, tôi sử dụng cùng một WHERE mệnh đề cập nhật giá trị:

UPDATE [dbo].[Occupation]
SET [JobTitle] = 'Unemployed'
WHERE [JobTitle] = 'Digital Nomad';

Bây giờ nếu tôi chạy kiểm tra lại, bản ghi đó không còn là vấn đề nữa và chỉ còn lại hai vấn đề khác:

DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;

Kết quả:

+------------------------+-------------------+---------------------------------------------------------+
| Table                  | Constraint        | Where                                                   |
|------------------------+-------------------+---------------------------------------------------------|
| [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' |
| [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' |
+------------------------+-------------------+---------------------------------------------------------+

Ví dụ 2 - Các Ràng buộc Khoá Ngoại bị Vi phạm

Trong ví dụ này, tôi chuyển sang cơ sở dữ liệu có một số vi phạm ràng buộc khóa ngoại.

USE Music;
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;

Kết quả:

+----------------+---------------------+--------------------+
| Table          | Constraint          | Where              |
|----------------+---------------------+--------------------|
| [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '123' |
| [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '17'  |
+----------------+---------------------+--------------------+

Trong trường hợp này, có vẻ như hai hàng trong Album bảng đang tham chiếu đến một ArtistId điều đó không tồn tại.

Tìm dữ liệu không hợp lệ

Một lần nữa, chúng ta có thể sử dụng Where để xây dựng WHERE của chúng tôi mệnh đề. Lần này, tôi sẽ thêm cả hai lỗi vi phạm vào WHERE của mình mệnh đề:

SELECT *
FROM [dbo].[Albums]
WHERE [ArtistId] = '123' OR [ArtistId] = '17';

Kết quả:

+-----------+-------------+---------------+------------+-----------+
| AlbumId   | AlbumName   | ReleaseDate   | ArtistId   | GenreId   |
|-----------+-------------+---------------+------------+-----------|
| 21        | Yo Wassup   | 2019-03-12    | 17         | 3         |
| 22        | Busted      | 1901-05-11    | 123        | 3         |
+-----------+-------------+---------------+------------+-----------+

Vì vậy, bây giờ chúng ta có thể thấy hai hàng vi phạm ràng buộc (mặc dù đó chỉ là ArtistId cột vi phạm ràng buộc).

Kiểm tra bảng khóa chính

Chúng tôi có thể xác nhận vi phạm bằng cách truy vấn Nghệ sĩ bảng (tức là bảng có chứa khóa chính cho khóa ngoại này).

Vì vậy, hãy chạy cùng một truy vấn với Nghệ sĩ bảng.

SELECT *
FROM [dbo].[Artists]
WHERE [ArtistId] = '123' OR [ArtistId] = '17';

Kết quả:

(0 rows affected)

Như mong đợi, không có giá trị nào trong bảng đó.

Khóa ngoại được cho là để ngăn điều này xảy ra. Dữ liệu không hợp lệ đã được nhập vào cơ sở dữ liệu trong khi khóa ngoại bị vô hiệu hóa hoặc được nhập trước khi khóa ngoại được tạo. Dù bằng cách nào, khi tạo hoặc bật khóa ngoại hoặc CHECK ràng buộc, bạn nên sử dụng WITH CHECK để chỉ định rằng tất cả dữ liệu hiện có phải được kiểm tra trước khi bật ràng buộc.

Ví dụ 3 - Chỉ chọn các Ràng buộc được Bật

Nếu bạn chỉ muốn kiểm tra các ràng buộc hiện đang được bật, hãy xóa WITH ALL_CONSTRAINTS :

USE Test;
DBCC CHECKCONSTRAINTS;

Kết quả:

+--------------------+---------------+------------------------------+
| Table              | Constraint    | Where                        |
|--------------------+---------------+------------------------------|
| [dbo].[Occupation] | [chkJobTitle] | [JobTitle] = 'Digital Nomad' |
+--------------------+---------------+------------------------------+

Vì vậy, trong số hai ràng buộc đã bị vi phạm, có vẻ như chkJobTitle là cái duy nhất được bật.

Chúng tôi có thể xác minh thêm điều này bằng truy vấn sau:

SELECT 
  name,
  is_disabled
FROM sys.check_constraints
WHERE name = 'chkValidEndDate' OR name = 'chkJobTitle';

Kết quả:

+-----------------+---------------+
| name            | is_disabled   |
|-----------------+---------------|
| chkJobTitle     | 0             |
| chkValidEndDate | 1             |
+-----------------+---------------+

Ví dụ 4 - Chỉ kiểm tra các ràng buộc cho một bảng đã cho

Bạn có thể thêm tên của bảng trong ngoặc đơn nếu bạn chỉ muốn kiểm tra các ràng buộc cho bảng đó:

USE Test;
DBCC CHECKCONSTRAINTS(ConstraintTest) WITH ALL_CONSTRAINTS;

Kết quả:

+------------------------+-------------------+---------------------------------------------------------+
| Table                  | Constraint        | Where                                                   |
|------------------------+-------------------+---------------------------------------------------------|
| [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' |
| [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' |
+------------------------+-------------------+---------------------------------------------------------+

Ví dụ 5 - Kiểm tra một ràng buộc duy nhất

Bạn có thể kiểm tra một ràng buộc duy nhất bằng cách đặt tên của nó bên trong các thông số:

USE Test;
DBCC CHECKCONSTRAINTS(chkValidEndDate);

Kết quả:

+------------------------+-------------------+---------------------------------------------------------+
| Table                  | Constraint        | Where                                                   |
|------------------------+-------------------+---------------------------------------------------------|
| [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' |
| [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' |
+------------------------+-------------------+---------------------------------------------------------+

Khi bạn chỉ định một ràng buộc duy nhất, WITH ALL_CONSTRAINTS không có hiệu lực:

USE Test;
DBCC CHECKCONSTRAINTS(chkValidEndDate) WITH ALL_CONSTRAINTS;

Kết quả:

+------------------------+-------------------+---------------------------------------------------------+
| Table                  | Constraint        | Where                                                   |
|------------------------+-------------------+---------------------------------------------------------|
| [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' |
| [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' |
+------------------------+-------------------+---------------------------------------------------------+

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách gửi kết quả truy vấn qua email trong SQL Server (T-SQL)

  2. Trình kích hoạt cập nhật SQL Server, Chỉ nhận các trường đã sửa đổi

  3. Tầng một ngày trong máy chủ SQL

  4. Hoàn tất quy trình sao chép bảng từ cơ sở dữ liệu này sang cơ sở dữ liệu khác (Xuất-nhập) trong SQL Server

  5. SQL Server - Giá trị trả về sau khi CHÈN