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

标签 sql-server sql-server-data-tools dacpac temporal

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

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

Creating [dbo].[TestHISTORY].[ix_TestHISTORY]...
An error occurred while the batch was being executed.
Updating database (Failed)
Could not deploy package.
Error SQL72014: .Net SqlClient Data Provider:

Msg 1913, Level 16, State 1, Line 1
The operation failed because an index or statistics with name 'ix_TestHISTORY' already exists on table 'dbo.TestHistory'.

Error SQL72045: Script execution error. The executed script:
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))

据我所知,问题出在 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

我怀疑是因为我们正在使用 temporal table with a default history table我们不能让 dacpac 创建那些额外的创建语句。因为这实际上导致 SQL Server 尝试创建这些项目两次,从而导致上述错误。

有人知道我们可能会错过什么吗?或者,如果您使用 dacpac 部署临时表,则使用 user-defined history tables 是您唯一的选择?

最佳答案

我们在时态表和 DACPAC 之间存在许多问题。一些大有帮助的提示:

  • 显式声明历史表 - 这比人们想象的要深入得多。添加/删除列时,您可以在历史表中定义默认值,从而绕过数据已存在于表中时出现的许多问题。
  • 为所有内容添加默认值 - 这一点怎么强调都不为过。默认值是 DACPAC 最好的 friend 。
  • 查看脚本 - 很高兴将 DACFx 视为不干涉,但事实并非如此。偶尔查看一下脚本,您将获得大量的见解(看来您已经是这样了!)
  • 明确命名您的索引 - DACFx 有时会使用索引/表/其他内容的临时名称。一致性才是王道,对吗?
  • 查看所有发布配置文件选项 - 有时,配置文件中有些设置是您没有想到的。我们进行了大量的手动干预后才意识到发布配置文件中存在事务脚本的设置。

还要调查谁将您的 DACPAC 变成了脚本。 VS 使用 SqlPackage.exe,但有时我会从 DACFx DLL 中得到不同的结果。两者之间的配置可能有所不同,但很难找出。两者都尝试一下,看看是否其中一个效果更好。

祝你好运!希望这有帮助!

关于sql-server - 如何使用 dacpac 和 SqlPackage.exe 部署时态表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49577201/

相关文章:

sql - SSIS 中的相交和排除结果如何

sql-server - 将本地数据库迁移到 sql azure 数据库时,它会忽略所有表创建脚本中的 DEFAULT (newid())

SQL 重叠日期

sql - 列出一个表的所有外键,同一个表的多个外键

visual-studio-2012 - 清除我的 TEMP 文件夹后,SSDT 无法构建数据项目

sql-server - SSIS 数据转换字符串到时间戳

sql - SqlAzureDacpacDeployment 中 SqlAdditionalArguments 的语法是什么

sql-server - sqlcmd 变量缺少值

sql-server - 在 MSSQL 触发器中使用 POST 方法