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ộtSELECT
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 là 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' | +------------------------+-------------------+---------------------------------------------------------+