直接執行 ALTER TABLE tbl DROP COLUMN col 失敗,錯誤訊息:
對象 'DF_tbl_col' 依賴於欄位 'col'。由於一或多個物件存取此欄位,ALTER TABLE DROP COLUMN 失敗。
原因:欄位擁有預設值約束,必須先移除約束才能刪除欄位。
-- 1. 取得預設約束名稱
DECLARE @df_name SYSNAME;
SELECT @df_name = dc.name
FROM sys.default_constraints dc
JOIN sys.columns c ON c.default_object_id = dc.object_id
JOIN sys.tables t ON t.object_id = c.object_id
WHERE t.name = 'tbl' AND c.name = 'col';
-- 2. 動態移除約束
IF @df_name IS NOT NULL
BEGIN
DECLARE @sql NVARCHAR(MAX) = N'ALTER TABLE dbo.tbl DROP CONSTRAINT ' + QUOTENAME(@df_name);
EXEC sp_executesql @sql;
END
-- 3. 刪除欄位
ALTER TABLE dbo.tbl DROP COLUMN col;
CREATE PROCEDURE dbo.usp_DropColumnWithDefault
@SchemaName SYSNAME,
@TableName SYSNAME,
@ColumnName SYSNAME
AS
BEGIN
SET NOCOUNT ON;
DECLARE @df_name SYSNAME;
SELECT @df_name = dc.name
FROM sys.default_constraints dc
JOIN sys.columns c ON c.default_object_id = dc.object_id
JOIN sys.tables t ON t.object_id = c.object_id
JOIN sys.schemas s ON s.schema_id = t.schema_id
WHERE s.name = @SchemaName AND t.name = @TableName AND c.name = @ColumnName;
IF @df_name IS NOT NULL
BEGIN
DECLARE @sql NVARCHAR(MAX) = N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' DROP CONSTRAINT ' + QUOTENAME(@df_name);
EXEC sp_executesql @sql;
PRINT '已移除預設約束: ' + @df_name;
END
DECLARE @drop_sql NVARCHAR(MAX) = N'ALTER TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' DROP COLUMN ' + QUOTENAME(@ColumnName);
EXEC sp_executesql @drop_sql;
PRINT '已刪除欄位: ' + @ColumnName;
END;
GO
-- 使用範例
EXEC dbo.usp_DropColumnWithDefault 'dbo', 'tbl', 'col';
同理適用於:CHECK、FOREIGN KEY(需先刪除 FK)、PRIMARY KEY。使用 sys.objects 依 type 篩選:D=DEFAULT, C=CHECK, F=FK, PK=PK。