Home · Blog · Schema changes

Schema changes

Before you rename a SQL Server column: find everything that will break

sp_rename lets you rename a column in one line. It doesn't cascade the change to anything that references that column. SQL Server won't warn you — it defers the error until someone executes the broken code path. Here's how to find everything at risk before you run the rename.

The danger: SQL Server uses late binding — views, functions, and procedures that reference a column by name continue to compile after the column is renamed. The failure is silent at rename time and surfaces only when the code path is executed.

Why sp_rename doesn't protect you

EXEC sp_rename 'dbo.Orders.OrderDate', 'order_date', 'COLUMN'; renames the column in the table definition and records the new name in the schema. It does not update any stored procedure, view, function, trigger, or computed column that references the old name. SQL Server's parser doesn't revalidate those objects at rename time — it resolves column names when the object is executed, not when it's compiled or when the schema changes underneath it.

The result: renaming a column silently invalidates every object that referenced the old name, and those objects will error at runtime — potentially in production, potentially days later when a code path that's only hit once a month runs for the first time after the rename.

Step 1: Find every object that references the table

Start broad. sys.sql_expression_dependencies tracks object-to-object references — every stored procedure, view, function, and trigger that names your table will appear here. Column-level tracking in this view is partial (it records some column references but not all), so the safest first step is a table-level blast radius:

SELECT
    d.referencing_entity_name,
    OBJECT_SCHEMA_NAME(d.referencing_id) AS referencing_schema,
    o.type_desc
FROM sys.sql_expression_dependencies AS d
JOIN sys.objects AS o ON o.object_id = d.referencing_id
WHERE d.referenced_entity_name = 'Orders'
  AND (d.referenced_schema_name = 'dbo' OR d.referenced_schema_name IS NULL)
ORDER BY o.type_desc, d.referencing_entity_name;

This is your candidate list — every object that touches the table and therefore might reference the column you're about to rename.

Step 2: Get column-level resolution via the DMF

sys.dm_sql_referenced_entities resolves dependencies at call time and returns column-level binding detail via referenced_minor_name. Run it against each object from step 1 that could reference the column:

SELECT
    referenced_entity_name,
    referenced_minor_name   AS referenced_column,
    is_selected,
    is_updated,
    is_select_all
FROM sys.dm_sql_referenced_entities('dbo.MonthlySalesSummary', 'OBJECT')
WHERE referenced_entity_name = 'Orders'
  AND referenced_minor_name = 'OrderDate';   -- the column you're renaming

If this returns rows, the object directly references the column by name and will break after the rename. Run this for each high-risk object — particularly views and functions that are themselves called by many other objects.

One operational caveat: sys.dm_sql_referenced_entities throws an error if the object doesn't compile cleanly. On databases with existing broken references, it may error before returning results. If that happens, fall back to step 3.

Step 3: Text search the module definitions

As a belt-and-suspenders check — and to catch dynamic SQL and any references the catalog view couldn't resolve — search the definition text of every SQL module in the database:

SELECT
    o.name,
    o.type_desc,
    m.definition
FROM sys.sql_modules AS m
JOIN sys.objects AS o ON o.object_id = m.object_id
WHERE m.definition LIKE '%OrderDate%'
ORDER BY o.type_desc, o.name;

Scan the definition column in the results. Most matches will be legitimate references to the column name. Watch for:

Don't forget: computed columns, indexes, and statistics

Three more places the old column name can live that aren't covered by the queries above:

-- Computed columns referencing the column
SELECT cc.name AS computed_column, cc.definition
FROM sys.computed_columns AS cc
WHERE cc.object_id = OBJECT_ID('dbo.Orders')
  AND cc.definition LIKE '%OrderDate%';

After you have the list

Once you know every object that references the column, the rename itself becomes a three-step operation:

  1. Run sp_rename on the column
  2. Run ALTER VIEW / ALTER PROCEDURE / ALTER FUNCTION on each affected object to update the column name in its definition
  3. Recompile and test each updated object in a non-production environment before applying to production

Doing step 2 before you have a complete list from steps 1–3 above is how you end up with partial fixes and a production incident on a code path you didn't know referenced the old name.

See the full object call graph before any schema change. Skupa maps sys.sql_expression_dependencies as an interactive diagram — click any object to see every caller upstream and every dependency downstream. Free 14-day trial.

Download free trial

← Back to blog · Find every dependency of a table →