What it means
ALTER TABLE … DROP COLUMN or ALTER COLUMN would pull the column out from under another object
that uses it, so SQL Server refuses. It prints one 5074 for each object in the way, then 4922 for the
statement:
Msg 5074, Level 16, State 1, Server 7732422b7f56, Line 1
The object 'DF__orders__status__25C68D63' is dependent on column 'status'.
Msg 4922, Level 16, State 9, Server 7732422b7f56, Line 1
ALTER TABLE DROP COLUMN status failed because one or more objects access this column.
The objects that can block a column:
- a default constraint (the
DF__…names are ones SQL Server generated); - an index, including one that only
INCLUDEs the column; - a primary key, foreign key,
UNIQUEorCHECKconstraint; - a view or function created
WITH SCHEMABINDING; - statistics created with
CREATE STATISTICS.
Common causes
- A default constraint you didn’t name.
ADD status varchar(20) NOT NULL DEFAULT 'new'creates a constraint named something likeDF__orders__status__25C68D63, different in every database, so a migration that drops the column fails, and a hard-codedDROP CONSTRAINTworks only where it was written. - An index on the column, which also blocks changing its type or length.
- Changing the type of a key column, such as an
intid tobigintonce it runs out of values (error 8115): the primary key and every foreign key on it are in the way. - A schema-bound view or function, often one behind an indexed view.
- Changing the type of a column with a default. Changing only the length, precision or scale
(
varchar(20)tovarchar(10)) is allowed; changing the type (varchartonvarchar) isn’t.
How to fix it
Drop the default constraint by looking up its name
Generated names differ between databases, so look the name up instead of hard-coding it:
DECLARE @sql nvarchar(max);
SELECT @sql = N'ALTER TABLE dbo.orders DROP CONSTRAINT ' + QUOTENAME(dc.name) + N';'
FROM sys.default_constraints AS dc
JOIN sys.columns AS c ON c.object_id = dc.parent_object_id AND c.column_id = dc.parent_column_id
WHERE dc.parent_object_id = OBJECT_ID(N'dbo.orders') AND c.name = N'status';
EXEC sys.sp_executesql @sql;
ALTER TABLE dbo.orders DROP COLUMN status;
To change the column instead of dropping it, alter it after dropping the default, then add the default back with a name you choose.
Find indexes, constraints and views on the column
-- indexes (key or included columns)
SELECT i.name AS index_name, i.type_desc
FROM sys.indexes AS i
JOIN sys.index_columns AS ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE i.object_id = OBJECT_ID(N'dbo.orders') AND COL_NAME(ic.object_id, ic.column_id) = N'total';
-- views, functions and CHECK constraints that refer to the column
SELECT OBJECT_SCHEMA_NAME(d.referencing_id) + N'.' + OBJECT_NAME(d.referencing_id) AS referencing_object
FROM sys.sql_expression_dependencies AS d
WHERE d.referenced_id = OBJECT_ID(N'dbo.orders')
AND COL_NAME(d.referenced_id, d.referenced_minor_id) = N'total';
Drop or alter each one, change the column, and re-create them, in one transaction:
BEGIN TRANSACTION;
DROP INDEX IX_orders_total ON dbo.orders;
ALTER TABLE dbo.orders ALTER COLUMN total decimal(12, 2) NOT NULL;
CREATE INDEX IX_orders_total ON dbo.orders (total);
COMMIT;
On a big table, changing a column’s type can rewrite every row and re-creating the index scans it, and both lock the table while they run; plan it for a quiet time.
Name your constraints from now on
A name you chose is the same in every database, so later migrations can drop it by name:
ALTER TABLE dbo.orders
ADD priority tinyint NOT NULL CONSTRAINT DF_orders_priority DEFAULT 0;
Reproduce it
On SQL Server 2022 (16.0.4295.3) with sqlcmd, a table
orders (…, status varchar(20) NOT NULL DEFAULT 'new', created_at datetime2 NOT NULL DEFAULT SYSUTCDATETIME())
in a scratch schema. Dropping status gave the 5074 and 4922 shown above. With an index on total,
then a WITH SCHEMABINDING view selecting created_at:
Msg 5074, Level 16, State 1, Server 7732422b7f56, Line 1
The index 'IX_orders_total' is dependent on column 'total'.
Msg 4922, Level 16, State 9, Server 7732422b7f56, Line 1
ALTER TABLE ALTER COLUMN total failed because one or more objects access this column.
Msg 5074, Level 16, State 1, Server 7732422b7f56, Line 1
The object 'DF__orders__created___26BAB19C' is dependent on column 'created_at'.
Msg 5074, Level 16, State 1, Server 7732422b7f56, Line 1
The object 'v_orders' is dependent on column 'created_at'.
Msg 4922, Level 16, State 9, Server 7732422b7f56, Line 1
ALTER TABLE DROP COLUMN created_at failed because one or more objects access this column.
Dropping customers.id listed both its primary key and FK_orders_customers, the foreign key on
orders. ALTER COLUMN status varchar(10) worked despite the default; ALTER COLUMN status nvarchar(20)
failed on it. A CREATE STATISTICS on created_at gave
The statistics 'ST_orders_created' is dependent on column 'created_at'. An index that only
included total (INCLUDE (total)) blocked dropping it too. The lookup above built
ALTER TABLE seo_err_mssql.orders DROP CONSTRAINT [DF__orders__status__25C68D63];, and the column
then dropped, inside a transaction we rolled back. SQL Server 2019 and 2025 printed the
same messages, with their own generated names.
In Inlet
Inlet’s structure designer for SQL Server writes named default constraints, so the columns it adds
don’t get generated names. It shows the T-SQL for a change before it runs, and warns when the change
rewrites or scans the table. A table’s definition shows its CREATE TABLE with constraints, indexes
and triggers, including the generated names. When SQL Server refuses, Inlet shows its message with
SQL Server error 5074, state 1, severity 16 and links to this page.