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

Cách khôi phục niềm tin trong ràng buộc khóa ngoại trong SQL Server (Ví dụ T-SQL)

Trong SQL Server, một ràng buộc khóa ngoại (và một CHECK ràng buộc) có thể được tin cậy hoặc không đáng tin cậy.

Khi một ràng buộc được tin cậy, điều này có nghĩa là ràng buộc đó đã được hệ thống xác nhận. Khi không đáng tin cậy, ràng buộc có không đã được hệ thống xác minh.

Về cơ bản, khi bạn có một ràng buộc không đáng tin cậy, bạn cũng có thể có dữ liệu không hợp lệ trong cơ sở dữ liệu của mình. Bởi điều này, tôi có nghĩa là bạn có thể có dữ liệu vi phạm ràng buộc.

Điều này có nghĩa là bạn không còn duy trì tính toàn vẹn tham chiếu trong các mối quan hệ của mình, đây là cách thường không tốt khi quản lý cơ sở dữ liệu quan hệ trong quá trình sản xuất.

Trong bài viết này, tôi sẽ kiểm tra các ràng buộc hiện có của mình để biết “độ tin cậy” của chúng, sau đó tôi sẽ cập nhật chúng để trở nên đáng tin cậy một lần nữa.

Ví dụ 1 - Xem lại các Ràng buộc Hiện tại

Bạn có thể tìm hiểu xem một ràng buộc có đáng tin cậy hay không bằng cách truy vấn sys.foreign_keys chế độ xem hệ thống.

Như thế này:

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Kết quả:

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 1             | 1                |
| FK_Albums_Genres  | 0             | 1                |
+-------------------+---------------+------------------+

OK, vì vậy điều này cho tôi biết tôi có hai ràng buộc khóa ngoại và cả hai đều không đáng tin cậy.

Một trong những ràng buộc bị vô hiệu hóa, do đó, có nghĩa là nó không đáng tin cậy (dữ liệu xấu có thể xâm nhập vào cơ sở dữ liệu bất cứ khi nào ràng buộc bị vô hiệu hóa).

Nhưng ràng buộc khác đã được kích hoạt, vì vậy nó thực sự không nên đáng tin cậy. Không đáng tin cậy có nghĩa là có thể có dữ liệu không hợp lệ trong cơ sở dữ liệu. Điều đó không có nghĩa là dữ liệu không hợp lệ, chỉ ở đó có thể là.

Về cơ bản, bằng cách được bật, nó sẽ kiểm tra dữ liệu trong tương lai, nhưng nó không thể đảm bảo cho dữ liệu hiện có. Nếu một ràng buộc được tin cậy, thì bạn có thể chắc chắn rằng tất cả dữ liệu hiện có đều hợp lệ.

Chỉ trả lại những ràng buộc không đáng tin cậy

Bạn có thể thấy thích sử dụng WHERE mệnh đề chỉ trả về các ràng buộc không đáng tin cậy. Như thế này:

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys
WHERE is_not_trusted = 1;

Kết quả:

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 1             | 1                |
| FK_Albums_Genres  | 0             | 1                |
+-------------------+---------------+------------------+

Vì vậy, trong trường hợp này, kết quả là như nhau (vì tất cả các ràng buộc hiện tại đều không đáng tin cậy).

Ví dụ 2 - Khôi phục độ tin cậy

Để khôi phục độ tin cậy cho ràng buộc đã bật của bạn, chỉ cần bật lại nó trong khi sử dụng WITH CHECK tùy chọn.

Như thế này:

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Genres;

Bây giờ khi chúng tôi truy vấn sys.foreign_keys chúng tôi nhận được một kết quả khác:

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Kết quả:

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 1             | 1                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Chúng ta có thể thấy rằng ràng buộc hiện được tin cậy vì is_not_trusted cờ được đặt thành 0 .

Ví dụ 3 - Ràng buộc trở nên không đáng tin cậy như thế nào?

Khi bạn vô hiệu hóa ràng buộc khóa ngoại, nó sẽ tự động trở nên không đáng tin cậy. Khi bạn kích hoạt lại cùng một ràng buộc, bạn có cơ hội khôi phục độ tin cậy của nó. Nếu bạn không làm điều này, nó sẽ vẫn không đáng tin cậy.

Khi bạn bật ràng buộc khóa ngoại, bạn có tùy chọn chỉ định WITH CHECK hoặc WITH NOCHECK . Nếu bạn chỉ định muộn hơn, ràng buộc của bạn sẽ vẫn không đáng tin cậy khi nó đã được kích hoạt.

Điều quan trọng cần lưu ý là WITH NOCHECK là tùy chọn mặc định, vì vậy nếu bạn không chỉ định rõ ràng rằng nó phải đáng tin cậy, thì ràng buộc sẽ được bật là không đáng tin cậy.

Tuy nhiên, điều ngược lại khi bạn tạo ràng buộc khóa ngoài. Khi bạn lần đầu tiên tạo ràng buộc, tùy chọn mặc định là WITH CHECK . Vì vậy, nếu bạn bỏ qua cài đặt này, cài đặt này sẽ được tin cậy theo mặc định (trừ khi bạn có dữ liệu không hợp lệ, trong trường hợp đó, cài đặt này sẽ không được bật). Tuy nhiên, bạn có thể ghi đè cài đặt này bằng cách chỉ định rõ ràng WITH NOCHECK khi bạn tạo ràng buộc.

Để chứng minh cách các ràng buộc đã bật của bạn có thể dễ dàng vẫn không đáng tin cậy, tôi sẽ bật lại khóa khác (khóa bị vô hiệu hóa), nhưng tôi sẽ sử dụng cài đặt mặc định:

ALTER TABLE Albums 
CHECK CONSTRAINT FK_Albums_Artists;

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Kết quả:

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 0             | 1                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Vì vậy, do lười biếng (hoặc đãng trí) và không chỉ định rõ ràng WITH CHECK , Tôi đã quản lý thành công để bật một hạn chế trong khi vẫn giữ nguyên trạng thái “không đáng tin cậy” của nó.

Chìa khóa rút ra từ điều này là:nếu bạn muốn các ràng buộc được bật lại của mình được tin cậy, bạn phải luôn bật chúng bằng cách sử dụng WITH CHECK .


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tìm các hàng trùng lặp trong SQL Server

  2. Hàm DECODE () trong SQL Server

  3. Cách chỉ định vị trí của tệp dữ liệu và tệp nhật ký khi tạo cơ sở dữ liệu trong SQL Server

  4. Điều kiện chạy hàng đợi quy trình SQL Server

  5. Làm cách nào để tìm kiếm tất cả các cột trong bảng?