外鍵約束阻止刪除父表資料或修改關鍵欄位,需先移除約束才能執行 DDL/DML。本文提供查詢約束名稱的多種方法(支援 2000/2005+)、刪除語法與驗證步驟。
-- 主表
CREATE TABLE test1 (id INT PRIMARY KEY NOT NULL, value INT);
INSERT test1 SELECT 1,2;
-- 從表(隱式建立外鍵)
CREATE TABLE test2 (id INT REFERENCES test1(id), value INT);
EXEC sp_helpconstraint 'test2';
結果集中 constraint_name 欄位即為外鍵名稱(如 FK__test2__id__08EA5793)。
SELECT fk.name AS constraint_name
FROM sys.foreign_key_columns fkc
JOIN sys.objects fk ON fkc.constraint_object_id = fk.object_id
WHERE fkc.parent_object_id = OBJECT_ID('test2');
輸出範例:
constraint_name ------------------------------- FK__test2__id__08EA5793
SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
WHERE TABLE_NAME = 'test2';
ALTER TABLE test2 DROP CONSTRAINT FK__test2__id__08EA5793;
DROP CONSTRAINT [FK__test2__id__08EA5793]。test2.id 不再受 test1.id 參考完整性限制。再次執行步驟一的任一查詢,**應無資料列返回**。
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + N'.' + QUOTENAME(OBJECT_NAME(parent_object_id))
+ N' DROP CONSTRAINT ' + QUOTENAME(name) + N';'
FROM sys.foreign_keys
WHERE referenced_object_id = OBJECT_ID('dbo.ParentTable'); -- 指定父表
EXEC sp_executesql @sql;
| 錯誤 | 原因 | 解決 |
|---|---|---|
| Msg 3728: 'FK_name' is not a constraint | 約束名稱錯誤/已不存在 | 先查詢確認名稱,使用方括號 |
| Msg 3725: The constraint 'FK_name' is being referenced | 該外鍵又被其他表參考(罕見多層級) | 遞迴刪除子表外鍵 |
| 刪除後資料完整性風險 | 應用層未同步驗證 | 務必在應用/觸發器/檢查約束中補償 |
CONSTRAINT FK_Child_Parent_Col FOREIGN KEY (col) REFERENCES Parent(col),避免系統產生難讀的亂碼名稱。掌握 sys.foreign_key_columns 查詢與 DROP CONSTRAINT 標準語法,即可安全、可腳本化地管理外鍵約束生命週期。