microsoft / DacFx

DacFx, SqlPackage, and other SQL development libraries enable declarative database development and database portability across SQL versions and environments. Share feedback here on dacpacs, bacpacs, and SQL projects.
https://aka.ms/sqlpackage-ref
MIT License
314 stars 19 forks source link

Table rebuilds when changing column type from VARCHAR(MAX) #361

Closed asrichesson closed 2 weeks ago

asrichesson commented 11 months ago

Steps to Reproduce:

  1. Create a table with a VARCHAR(MAX) column
  2. Deploy the table
  3. Change the column from VARCHAR(MAX) to VARCHAR(250)
  4. Expected: sqlpackage emits an ALTER Column statement
  5. Actual: sqlpackage emits a table rebuild

Change

CREATE TABLE TestTable(Col VARCHAR(MAX))

To

CREATE TABLE TestTable(Col VARCHAR(250))

Results in:

CREATE TABLE [dbo].[tmp_ms_xx_TestTable] (
    [Col] VARCHAR (250) NULL
);
IF EXISTS (SELECT TOP 1 1 
           FROM   [dbo].[TestTable])
    BEGIN
        INSERT INTO [dbo].[tmp_ms_xx_TestTable] ([Col])
        SELECT [Col]
        FROM   [dbo].[TestTable];
    END
DROP TABLE [dbo].[TestTable];
EXECUTE sp_rename N'[dbo].[tmp_ms_xx_TestTable]', N'TestTable';

Why is this a problem? Table rebuilds are bad and often impossible to do on extremely large tables with high usage. For simple column table data changes, I expect sqlpackage to script simple ALTER statements.

Did this occur in prior versions? If not - which version(s) did it work in?

(DacFx/SqlPackage/SSMS/Azure Data Studio)

asrichesson commented 10 months ago

Changing the scale on a decimal column also causes a table rebuild. Change

Create Table TestTable(Col1 DECIMAL(11,4))

To

Create Table TestTable(Col1 DECIMAL(11,5))
namangupta211 commented 7 months ago

Thanks for reaching out to us. Yes, there are cases when table gets rebuild because of small, sometimes unnecessary changes. This is an existing problem and Sqlpackage team is working on it. Meanwhile you can use a publish option, /p: AllowTableRecreation, which specifies whether to allow table recreation during deployment if required to perform the schema change. If you set it to False, then the deployment will halt and let you know which tables are getting recreated.

https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage-publish?view=sql-server-ver16