หลังจากที่ได้อ่าน MS DOCS ที่นี่
เพื่อปรับเปลี่ยนรหัสต่างประเทศ
ในการแก้ไขข้อ จำกัด ของ FOREIGN KEY โดยใช้ Transact-SQL คุณต้องลบข้อ จำกัด ของ FOREIGN KEY ที่มีอยู่ก่อนแล้วจึงสร้างมันขึ้นใหม่ด้วยคำจำกัดความใหม่ สำหรับข้อมูลเพิ่มเติมดูลบความสัมพันธ์กับต่างประเทศที่สำคัญและสร้างความสัมพันธ์ที่สำคัญต่างประเทศ
ในกรณีที่ฉันเชื่อว่าเพิ่ม FK ใหม่และลบอันเก่า หากต้องการปิดใช้งานการสแกนคุณสามารถใช้NO CHECK
ตัวเลือก
--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 ║
╚══════════╩════════════╩═════════════════╩══════════════╝
ดูว่ามันใช้งานได้หรือไม่สิ่งที่ฉันพยายามคือการเพิ่ม FK อีกหนึ่งรายการใหม่เพื่อเชื่อมโยงกับดัชนีใหม่ที่สร้างขึ้นและปล่อย FK เก่า ฉันรู้ว่าคำถามนี้ไม่ได้เป็นการทิ้งคำถามที่มีอยู่ แต่ดูว่าตัวเลือกนี้จะช่วยคุณได้หรือไม่
นอกจากนี้ตามความคิดเห็นจาก Max Vernon: "ตัวเลือก WITH NOCHECK จะป้องกันไม่ให้ foreign key เชื่อถือได้โดย optimizer ในบางจุดคุณจะต้องเปลี่ยน foreign key เพื่อให้เชื่อถือได้โดยใช้ ALTER TABLE ... ด้วยการตรวจสอบ "
NOCHECK
จะถูกละเว้นเฉพาะในช่วงเวลาของการสร้าง แต่การบังคับใช้ contraint สมบูรณ์ที่คุณได้ทำนี้ในบางจุดของเวลา