sqlsql-serverdatabasepublishdatabase-project

SSDT Drop and Recreate Tables when nothing has changed


I'm using SSDT database project to create deployment scripts for my database.
One of the tables, [AdrInfo].[IL] is dropped and then recreated every time when the deployment runs.
Nothing has changed in the definition of the tables in the project files.
Definition of the table:

CREATE TABLE [AdrInfo].[IL] (
        [IL_ID]      NVARCHAR (50) NULL,
        [IL_ADI]     NVARCHAR (50) NULL,
        [XCOOR]      VARCHAR (50)  NULL,
        [YCOOR]      VARCHAR (50)  NULL,
        [IL_ADI_KEY] AS            (CONVERT (NVARCHAR (255), replace(replace([IL_ADI], ' ', ''), '.', ''), 0) COLLATE SQL_Latin1_General_Cp850_CI_AI) PERSISTED );

CREATE CLUSTERED INDEX [index_IX_IL_CI1] ON [AdrInfo].[IL]([IL_ADI_KEY] ASC);

Snippet from deployment script:


    GO PRINT N'Starting rebuilding table [AdrInfo].[IL]...';


    GO BEGIN TRANSACTION;

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

    SET XACT_ABORT ON;

    CREATE TABLE [AdrInfo].[tmp_ms_xx_IL] (
        [IL_ID]      NVARCHAR (50) NULL,
        [IL_ADI]     NVARCHAR (50) NULL,
        [XCOOR]      VARCHAR (50)  NULL,
        [YCOOR]      VARCHAR (50)  NULL,
        [IL_ADI_KEY] AS            (CONVERT (NVARCHAR (255), replace(replace([IL_ADI], ' ', ''), '.', ''), 0) COLLATE SQL_Latin1_General_Cp850_CI_AI) PERSISTED );

    CREATE CLUSTERED INDEX [tmp_ms_xx_index_IX_IL_CI1]
        ON [AdrInfo].[tmp_ms_xx_IL]([IL_ADI_KEY] ASC);

I would expect SSDT to not touch this table during deployment. What can cause such a behavior?


Solution

  • SSDT is very picky when deploying default expressions for table columns.
    Please compare expressions below:

     (CONVERT (NVARCHAR (255), replace(replace([IL_ADI], ' ', ''), '.', ''), 0)  COLLATE SQL_Latin1_General_Cp850_CI_AI) PERSISTED 
    ((CONVERT (NVARCHAR (255), replace(replace([IL_ADI], ' ', ''), '.', ''), 0)) COLLATE SQL_Latin1_General_Cp850_CI_AI) PERSISTED 
    

    Using 1st one will cause the table to be redeployed every time, using the second one will stop this behavior. SQL Server do not store default expressions as text, but normalizes them. SSDT uses own normalization and then compares it to normalized expression.
    If the both sets of normalization rules are not creating the same expression, SSDT will redeploy the column expression every time, which was causing redeploying the table in your case.
    To avoid it, use SSMS script table to get normalized expression and save it in the project file.