KIỂM TRA KIỂM TRA KIỂM TRA LÀ GÌ?


18

Tôi có một số T-SQL được tạo tự động, có thể hợp lệ, nhưng tôi không thực sự hiểu.

ALTER TABLE [dbo].[MyTable]
WITH CHECK
CHECK CONSTRAINT [My_FORIEGN_KEY];

Tôi biết ràng buộc khóa ngoại là gì, nhưng đó là CHECK CHECKgì?

Câu trả lời:


27

Trang tài liệu MSDN về ALTER TABLEgiải thích những điều này:

  • ALTER TABLE: sửa đổi cấu trúc của bảng
    (và một số hành động / sửa đổi có thể có):
    • CHECK CONSTRAINT ..: kích hoạt các ràng buộc
    • NOCHECK CONSTRAINT ..: vô hiệu hóa ràng buộc
      Ngoài ra còn có các bước bổ sung, tùy chọn cần thực hiện trong khi tạo / bật / tắt ràng buộc:
      • WITH CHECK: kiểm tra các ràng buộc là tốt
      • WITH NOCHECK: không kiểm tra ràng buộc

Theo cách nói của họ:

| [ WITH { CHECK | NOCHECK } ] { CHECK | NOCHECK } CONSTRAINT   
    { ALL | constraint_name [ ,...n ] }

...

WITH CHECK | WITH NOCHECK Chỉ định liệu dữ liệu trong bảng có hoặc không được xác thực đối với ràng buộc mới được thêm hoặc bật lại FOREIGN KEYhoặc CHECKràng buộc . Nếu không được chỉ định, WITH CHECKđược giả sử cho các ràng buộc mới và WITH NOCHECKđược giả định cho các ràng buộc được kích hoạt lại.

Nếu bạn không muốn xác minh mới CHECKhoặc các FOREIGN KEYràng buộc đối với dữ liệu hiện có, hãy sử dụng WITH NOCHECK. Chúng tôi không khuyên bạn nên làm điều này, trừ trường hợp hiếm. Các ràng buộc mới sẽ được đánh giá trong tất cả các cập nhật dữ liệu sau này. Bất kỳ vi phạm ràng buộc nào bị loại bỏ WITH NOCHECKkhi ràng buộc được thêm vào có thể khiến các cập nhật trong tương lai không thành công nếu chúng cập nhật các hàng với dữ liệu không tuân thủ ràng buộc.

Trình tối ưu hóa truy vấn không xem xét các ràng buộc được xác định WITH NOCHECK. Các ràng buộc như vậy được bỏ qua cho đến khi chúng được kích hoạt lại bằng cách sử dụng ALTER TABLEbảng WITH CHECK CHECK CONSTRAINT ALL.

...

{ CHECK | NOCHECK } CONSTRAINT
Chỉ định rằng ràng buộc tên được bật hoặc tắt. Tùy chọn này chỉ có thể được sử dụng với FOREIGN KEYvà các CHECKràng buộc. Khi NOCHECKđược chỉ định, ràng buộc bị vô hiệu hóa và các lần chèn hoặc cập nhật trong tương lai vào cột không được xác thực theo các điều kiện ràng buộc. DEFAULT, PRIMARY KEYvà các UNIQUEràng buộc không thể bị vô hiệu hóa.

Kiểm tra trong dbfiddle :

CREATE TABLE a (aid INT PRIMARY KEY);

ĐI

INSERT INTO a (aid)
VALUES (1), (2), (3) ;

ĐI

3 hàng bị ảnh hưởng
CREATE TABLE b 
( aid INT,
  bid INT PRIMARY KEY,
  CONSTRAINT [My_FORIEGN_KEY]
    FOREIGN KEY (aid) REFERENCES a (aid)
) ;

ĐI

INSERT INTO b (aid, bid)
VALUES
  (1, 11),
  (1, 12),
  (2, 21), 
  (3, 31) ;

ĐI

4 hàng bị ảnh hưởng
INSERT INTO b (aid, bid)
VALUES
  (6, 61),
  (6, 62) ;

ĐI

Msg 547 Cấp 16 Bang 0 Dòng 1
Câu lệnh INSERT đã xung đột với ràng buộc FOREIGN KEY "My_FORIEGN_KEY". Xung đột xảy ra trong cơ sở dữ liệu "fiddle_792fce5de09f42908c3a0f91421f3522", bảng "dbo.a", cột 'viện trợ'.
Msg 3621 Cấp 0 Nhà nước 0 Dòng 1
Các tuyên bố này đã bị chấm dứt.
SELECT * FROM b ;

ĐI

viện trợ | đấu thầu
-: | -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
ALTER TABLE b NOCHECK CONSTRAINT [My_FORIEGN_KEY];   --disable

ĐI

INSERT INTO b (aid, bid)
VALUES
  (4, 41),
  (4, 42) ;

ĐI

2 hàng bị ảnh hưởng
SELECT * FROM b ;

ĐI

viện trợ | đấu thầu
-: | -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
  4 | 41
  4 | 42
ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY];  
-- enable constraint without checking existing data

ĐI

SELECT * FROM b ;

ĐI

viện trợ | đấu thầu
-: | -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
  4 | 41
  4 | 42
INSERT INTO b (aid, bid)
VALUES
  (6, 61),
  (6, 62) ;

ĐI

Msg 547 Cấp 16 Bang 0 Dòng 1
Câu lệnh INSERT đã xung đột với ràng buộc FOREIGN KEY "My_FORIEGN_KEY". Xung đột xảy ra trong cơ sở dữ liệu "fiddle_792fce5de09f42908c3a0f91421f3522", bảng "dbo.a", cột 'viện trợ'.
Msg 3621 Cấp 0 Nhà nước 0 Dòng 1
Các tuyên bố này đã bị chấm dứt.
SELECT * FROM b ;

ĐI

viện trợ | đấu thầu
-: | -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
  4 | 41
  4 | 42
ALTER TABLE b WITH CHECK CHECK CONSTRAINT [My_FORIEGN_KEY];  
-- check existing data and enable constraint 

ĐI

Msg 547 Cấp 16 Bang 0 Dòng 1
Câu lệnh ALTER TABLE đã xung đột với ràng buộc FOREIGN KEY "My_FORIEGN_KEY". Xung đột xảy ra trong cơ sở dữ liệu "fiddle_792fce5de09f42908c3a0f91421f3522", bảng "dbo.a", cột 'viện trợ'.

1
Cảm ơn. Wrt ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- enable constraint without checking, điều này có nghĩa là các ràng buộc sẽ không kiểm tra dữ liệu hiện có, chỉ có dữ liệu mới đến?
BanksySan

1
Chính xác. Xem cách chèn tiếp theo (Aid = 6) không được phép nhưng các hàng hiện có (với Aid = 4) vẫn còn đó.
ypercubeᵀᴹ

Điều đó chứng tỏ nó hoàn hảo.
BanksySan

1

Xem xét việc đọc bài viết ở đây: https://msdn.microsoft.com/en-us/l Library / ms190273.aspx

Nó cho chúng ta biết: 'Trình tối ưu hóa truy vấn không xem xét các ràng buộc được xác định với NOCHECK. Các ràng buộc như vậy được bỏ qua cho đến khi chúng được kích hoạt lại bằng cách sử dụng bảng ALTER TABLE VỚI KIỂM TRA KIỂM TRA TẤT CẢ '

Ngoài ra, hãy xem xét chủ đề thi trên StackOverflow: /programming/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.