如何使用dacpac和SqlPackage.exe部署时态表

lar*_*ice 8 sql-server temporal dacpac sql-server-data-tools

我们正在尝试使用SQL Server 2016中的时态表.我们正在Visual Studio 2017中开发SSDT 15.1.6中的SQL脚本,但是在尝试部署构建期间生成的dacpac时遇到了问题.

我们的dacpac是使用部署的SqlPackage.exe,在尝试部署dacpac时遇到此错误:

创建[dbo].[TestHISTORY].[ix_TestHISTORY] ...
正在执行批处理时发生错误.
更新数据库(失败)
无法部署包.
错误SQL72014:.Net SqlClient数据提供程序:

消息1913,级别16,状态1,行1
操作失败,因为表'dbo.TestHistory'上已存在名为'ix_TestHISTORY'的索引或统计信息.

错误SQL72045:脚本执行错误.执行的脚本:
CREATE CLUSTERED INDEX [ix_TestHISTORY] ON [dbo].[TestHistory]([SysStart] ASC,[SysEnd] ASC);

当我们在SSDT中创建时态表时,我们有以下内容:

CREATE TABLE [dbo].[Test]
(
    [Id] INT NOT NULL PRIMARY KEY,
    [SysStart] DATETIME2 (7) GENERATED ALWAYS AS ROW START NOT NULL,
    [SysEnd] DATETIME2 (7) GENERATED ALWAYS AS ROW END NOT NULL,
    PERIOD FOR SYSTEM_TIME ([SysStart], [SysEnd])
)
WITH (SYSTEM_VERSIONING = ON(HISTORY_TABLE=[dbo].[TestHISTORY], DATA_CONSISTENCY_CHECK=ON))
Run Code Online (Sandbox Code Playgroud)

据我所知,问题在于dacpac的创造.项目构建完成后,创建的dacpac如下所示:

CREATE TABLE [dbo].[test]  
(
    [Id]       INT NOT NULL PRIMARY KEY CLUSTERED ([Id] ASC),
    [SysStart] DATETIME2 (7) GENERATED ALWAYS AS ROW START NOT NULL,
    [SysEnd]   DATETIME2 (7) GENERATED ALWAYS AS ROW END   NOT NULL,
    PERIOD FOR SYSTEM_TIME ([SysStart], [SysEnd])
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE=[dbo].[testHISTORY], DATA_CONSISTENCY_CHECK=ON));
GO

CREATE TABLE [dbo].[testHISTORY] 
(
    [Id]       INT           NOT NULL,
    [SysStart] DATETIME2 (7) NOT NULL,
    [SysEnd]   DATETIME2 (7) NOT NULL
);
GO

CREATE CLUSTERED INDEX [ix_testHISTORY]
    ON [dbo].[testHISTORY]([SysEnd] ASC, [SysStart] ASC);
GO
Run Code Online (Sandbox Code Playgroud)

我怀疑因为我们正在使用带有默认历史表的时态表,所以我们不能让dacpac创建那些额外的创建语句.由于这有效地导致SQL Server尝试两次创建这些项目,从而导致上述错误.

有谁知道我们可能会缺少什么?或者,如果使用dacpac部署时态表,那么使用用户定义的历史表是唯一的选择吗?

Tra*_*ing 7

临时表和DACPAC之间存在许多问题。一些技巧将大有帮助:

  • 显式声明历史记录表-这超出了人们的想象。添加/删除列时,可以在历史记录表上定义默认值,从而可以绕过表中已有数据时出现的许多问题。
  • 将默认值添加到所有内容-这不能被夸大。默认值是DACPAC的最好朋友。
  • 查看脚本-可以轻松地想到DACFx,但事实并非如此。偶尔查看一下脚本,您将获得大量的见解(看来您已经!)
  • 明确命名索引-DACFx有时将临时名称用于索引/表/其他内容。一致性是国王,对不对?
  • 查看所有发布配置文件选项-有时,您在配置文件中没有想到某些设置。在意识到发布配置文件中存在用于事务脚本的设置之前,我们花费了很多手动干预。

还要研究谁将您的DACPAC转换为脚本。VS使用SqlPackage.exe,但是有时我从DACFx DLL中得到不同的结果。两者之间的配置可能有所不同,但是很难找出来。只需尝试两者,看看是否效果更好。

祝你好运!希望这可以帮助!