Sau khi đọc MS DOCS tại đây .
Để sửa đổi khóa ngoại
Để sửa đổi ràng buộc FOREIGN KEY bằng cách sử dụng Transact-SQL, trước tiên bạn phải xóa ràng buộc FOREIGN KEY hiện có và sau đó tạo lại nó với định nghĩa mới. Để biết thêm thông tin, hãy xem Xóa Mối quan hệ Khóa ngoài và Tạo Mối quan hệ Khóa ngoài.
Trong trường hợp của bạn, tôi tin rằng thêm một FK mới và xóa cái cũ. Để tắt tính năng quét, bạn có thể sử dụng NO CHECK
tùy chọn
--DROP TABLE T2
--DROP TABLE T1
CREATE TABLE T1 (
[Id] INT,
[NAME] varchar(100), CONSTRAINT [PK_T1] PRIMARY KEY CLUSTERED (id))
CREATE TABLE T2 (
t2_id int,
T1_Id INT NOT NULL
,CONSTRAINT [FK_T2_T1] FOREIGN KEY (T1_Id) REFERENCES T1(Id)
)
CREATE UNIQUE NONCLUSTERED INDEX IX_T1_Id ON T1 (Id)
select
ix.index_id,
ix.name as index_name,
ix.type_desc as index_type_desc,
fk.name as fk_name
from sys.indexes ix
left join sys.foreign_keys fk on
fk.referenced_object_id = ix.object_id
and fk.key_index_id = ix.index_id
and fk.parent_object_id = object_id('T2')
where ix.object_id = object_id('T1');
╔══════════╦════════════╦═════════════════╦══════════╗
║ index_id ║ index_name ║ index_type_desc ║ fk_name ║
╠══════════╬════════════╬═════════════════╬══════════╣
║ 1 ║ PK_T1 ║ CLUSTERED ║ FK_T2_T1 ║
║ 2 ║ IX_T1_Id ║ NONCLUSTERED ║ NULL ║
╚══════════╩════════════╩═════════════════╩══════════╝
ALTER TABLE T2
WITH NOCHECK
ADD CONSTRAINT [FK_T2_T1_NEW] FOREIGN KEY(T1_Id)
REFERENCES T1(Id)
select
ix.index_id,
ix.name as index_name,
ix.type_desc as index_type_desc,
fk.name as fk_name
from sys.indexes ix
left join sys.foreign_keys fk on
fk.referenced_object_id = ix.object_id
and fk.key_index_id = ix.index_id
and fk.parent_object_id = object_id('T2')
where ix.object_id = object_id('T1');
╔══════════╦════════════╦═════════════════╦══════════════╗
║ index_id ║ index_name ║ index_type_desc ║ fk_name ║
╠══════════╬════════════╬═════════════════╬══════════════╣
║ 1 ║ PK_T1 ║ CLUSTERED ║ FK_T2_T1 ║
║ 2 ║ IX_T1_Id ║ NONCLUSTERED ║ FK_T2_T1_NEW ║
╚══════════╩════════════╩═════════════════╩══════════════╝
ALTER TABLE T2
DROP CONSTRAINT FK_T2_T1
select
ix.index_id,
ix.name as index_name,
ix.type_desc as index_type_desc,
fk.name as fk_name
from sys.indexes ix
left join sys.foreign_keys fk on
fk.referenced_object_id = ix.object_id
and fk.key_index_id = ix.index_id
and fk.parent_object_id = object_id('T2')
where ix.object_id = object_id('T1');
╔══════════╦════════════╦═════════════════╦══════════════╗
║ index_id ║ index_name ║ index_type_desc ║ fk_name ║
╠══════════╬════════════╬═════════════════╬══════════════╣
║ 1 ║ PK_T1 ║ CLUSTERED ║ NULL ║
║ 2 ║ IX_T1_Id ║ NONCLUSTERED ║ FK_T2_T1_NEW ║
╚══════════╩════════════╩═════════════════╩══════════════╝
Xem nếu điều này hoạt động, những gì tôi đang cố gắng là thêm một FK nữa để cái mới được liên kết với chỉ mục mới được tạo và loại bỏ FK cũ. Tôi biết câu hỏi không phải là bỏ câu hỏi hiện tại nhưng hãy xem liệu tùy chọn này có giúp bạn không.
Ngoài ra, theo nhận xét từ Max Vernon: "tùy chọn VỚI NOCHECK sẽ ngăn khóa ngoại được tin tưởng bởi trình tối ưu hóa. Đến một lúc nào đó, bạn phải thay đổi khóa ngoại để nó được tin cậy khi sử dụng ALTER TABLE ... VỚI KIỂM TRA "
Ý NOCHECK
chí chỉ được bỏ qua tại thời điểm tạo ra nhưng để thực thi chống lại tính toàn vẹn, bạn đã chạy nó vào một lúc nào đó.