IgnoreColumnOrder not working with temporal tables
kerwinc opened this issue · comments
Hi Guys,
We are experiencing major issues managing temporal tables through SSDT. One major issue is that simple column changes are causing table rebuilds.
Problem
Adding columns to temporal tables are triggering table rebuilds which is a big problem for realtime systems or tables with lots of data. IgnoreColumnOrder=True does not work for temporal tables. I tried configuring the desired behaviour by using a publish profile and specifying the property directly ( /p:IgnoreColumnOrder=true ) resulting in the same output.
Change Script Result:
PRINT N'Starting rebuilding table [dbo].[tb_Settings]...';
BEGIN TRANSACTION;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET XACT_ABORT ON;
CREATE TABLE [dbo].[tmp_ms_xx_tb_Settings] (
[SettingId] INT NOT NULL,
[Key] NVARCHAR (255) NOT NULL,
[DisplayName] NVARCHAR (255) NOT NULL,
[Description] NVARCHAR (MAX) NULL,
[DateTimeValue2] DATETIME2 (2) NULL,
[Value] NVARCHAR (255) NULL,
[SysStart] DATETIME2 (2) GENERATED ALWAYS AS ROW START NOT NULL,
[SysEnd] DATETIME2 (2) GENERATED ALWAYS AS ROW END NOT NULL,
[DateValue] DATETIME2 (2) NULL,
CONSTRAINT [tmp_ms_xx_constraint_PK_SettingId1] PRIMARY KEY CLUSTERED ([SettingId] ASC),
PERIOD FOR SYSTEM_TIME ([SysStart], [SysEnd])
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE=[dbo].[tb_Settings_HISTORY], DATA_CONSISTENCY_CHECK=ON));
IF EXISTS (SELECT TOP 1 1
FROM [dbo].[tb_Settings])
BEGIN
IF EXISTS (SELECT TOP 1 1
FROM [sys].[tables]
WHERE [name] = N'tmp_ms_xx_tb_Settings'
AND SCHEMA_NAME(schema_id) = N'dbo'
AND temporal_type = 2)
BEGIN
ALTER TABLE [dbo].[tmp_ms_xx_tb_Settings] SET (SYSTEM_VERSIONING = OFF);
END
IF EXISTS (SELECT TOP 1 1
FROM [sys].[periods]
WHERE [period_type] = 1
AND OBJECT_ID('[dbo].[tmp_ms_xx_tb_Settings]', 'U') = object_id)
BEGIN
ALTER TABLE [dbo].[tmp_ms_xx_tb_Settings] DROP PERIOD FOR SYSTEM_TIME;
END
INSERT INTO [dbo].[tmp_ms_xx_tb_Settings] ([SettingId], [Key], [DisplayName], [Description], [Value], [DateTimeValue2], [SysStart], [SysEnd], [DateValue])
SELECT [SettingId],
[Key],
[DisplayName],
[Description],
[Value],
[DateTimeValue2],
[SysStart],
[SysEnd],
[DateValue]
FROM [dbo].[tb_Settings]
ORDER BY [SettingId] ASC;
ALTER TABLE [dbo].[tmp_ms_xx_tb_Settings]
ADD PERIOD FOR SYSTEM_TIME (SysStart, SysEnd);
ALTER TABLE [dbo].[tmp_ms_xx_tb_Settings] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE=[dbo].[tb_Settings_HISTORY], DATA_CONSISTENCY_CHECK=ON));
END
IF EXISTS (SELECT TOP 1 1
FROM [sys].[tables]
WHERE [name] = N'tb_Settings'
AND SCHEMA_NAME(schema_id) = N'dbo'
AND temporal_type = 2)
BEGIN
ALTER TABLE [dbo].[tb_Settings] SET (SYSTEM_VERSIONING = OFF);
END
DROP TABLE [dbo].[tb_Settings];
EXECUTE sp_rename N'[dbo].[tmp_ms_xx_tb_Settings]', N'tb_Settings';
EXECUTE sp_rename N'[dbo].[tmp_ms_xx_constraint_PK_SettingId1]', N'PK_SettingId', N'OBJECT';
COMMIT TRANSACTION;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Testing
Tested using SQLPackage 18.5 and 18.5.1.
Please advise if this can be resolved in the next version of SQLPackage / DacFx.
What is the definition of the column you are adding?
[DateTimeValue2] DATETIME2 (2) NULL,
Just re-ordering the columns in the temporal table triggers a rebuild. IgnoreColumnOrder works fine for normal tables.
closing instead of transferring since a duplicate exists on dacfx repo