Troubleshooting Guide: Error 4934 – Computed Column Cannot Be Persisted
Why This Error Happens
This error occurs because SQL Server requires that any computed column marked as PERSISTED be fully deterministic and free of any dependency on external data sources. If the computed column’s expression calls a user-defined function (UDF) that performs data access (such as querying another table) or uses certain system functions that access external state, SQL Server cannot guarantee the value is deterministic or safely calculable without a full data access context, so it blocks the PERSISTED or indexing operation. This is a validation rule enforced by the Query Optimizer and Storage Engine during table creation (CREATE TABLE) or alteration (ALTER TABLE), not a configuration or connectivity issue.
Step-by-Step Resolution Guide
Step 1: Identify the Offending Function in the Column Definition
- Locate the exact table and column referenced in the error message (e.g.,
table 'dbo.Orders', column'TotalWithTax'). - Run the following query to inspect the column definition:
SELECT name, definition, is_persisted
FROM sys.computed_columns
WHERE object_id = OBJECT_ID('dbo.Orders');
- Check if the expression calls a scalar UDF,
CLRfunction, or system function like@@SERVERNAME,RAND(), orNEWID()that are non-deterministic or access-dependent.
Step 2: Verify Function Determinism and Data Access Property
- If a User-Defined Function (UDF) is involved, check its properties using:
SELECT OBJECTPROPERTY(OBJECT_ID('dbo.YourFunctionName'), 'IsDeterministic') AS IsDeterministic,
OBJECTPROPERTY(OBJECT_ID('dbo.YourFunctionName'), 'IsSystemVerified') AS IsSystemVerified;
- If
IsDeterministicreturns0, the function is disqualified from being used in a persisted column. - Ensure the UDF does not contain any
SELECTstatements referencing tables within the function body; it must rely solely on input parameters.
Step 3: Modify the Function or Remove the PERSISTED Keyword
- Option A (Recommended): Rewrite the UDF to remove any internal table queries, relying only on passed-in parameters to make it deterministic.
- Option B (Quick Fix): If the logic must access data, drop the
PERSISTEDkeyword from the column definition since non-deterministic columns cannot be physically stored:
ALTER TABLE dbo.Orders
ALTER COLUMN TotalWithTax AS (dbo.CalculateTax(OrderID));
- Option C: Replace the data-accessing UDF logic with an inline scalar expression or a deterministic built-in function if possible.
Step 4: Re-deploy the Schema Change
- Drop and recreate the table or column with the updated computed column logic.
- If using Entity Framework or a migration script, update the model snapshot to remove the
Persistedattribute flag for this specific property to match the SQL Server constraint.
Alternative or Verification Steps
- Verification: After altering the column, run
DBCC CHECKCONSTRAINTSor simply re-run the originalALTER TABLEscript; if Error 4934 does not reappear, the schema change was successful. - Alternative: If the business logic strictly requires data access for this calculation, use an
INSTEAD OForAFTERTrigger to populate a standard (non-computed) column instead of relying on thePERSISTEDcomputed column feature.