在部署dacpac时,如何防止SqlPackage.exe丢弃并重新创建约束?

时间:2015-12-16 21:14:58

标签: sql sql-server sqlpackage

我有一个Visual Studio sql项目,其表格定义如下:

CREATE TABLE [dbo].[Hoerses]
(
   [HoersId] INT NOT NULL PRIMARY KEY,
   [DatePurchased] datetime NOT NULL CONSTRAINT [DF_Hoerses_DatePurchased] DEFAULT DATETIMEFROMPARTS(1985,01,01,0,0,0,0)
)

当我使用"脚本"来定位预先存在的SQL数据库时命令

sqlpackage.exe /Action:Script /SourceFile:DatabaseProject1.dacpac  /Profile:publish.xml /OutputPath:deployscript_test.sql /TargetPassword:redacted

然后我得到以下生成的SQL,即使约束在&之前具有相同的名称和定义。后:

PRINT N'Dropping [dbo].[DF_Hoerses_DatePurchased]...';


GO
ALTER TABLE [dbo].[Hoerses] DROP CONSTRAINT [DF_Hoerses_DatePurchased];


GO
PRINT N'Creating [dbo].[DF_Hoerses_DatePurchased]...';


GO
ALTER TABLE [dbo].[Hoerses]
    ADD CONSTRAINT [DF_Hoerses_DatePurchased] DEFAULT DATETIMEFROMPARTS(1985,01,01,0,0,0,0) FOR [DatePurchased];


GO
PRINT N'Update complete.';


GO

(我主要担心试图阻止这种多余的重新创建是因为我偶尔会看到超过锁定请求超时时间。"错误时它试图放弃约束实际部署/发布)

3 个答案:

答案 0 :(得分:2)

问题显然在于使用DATETIMEFROMPARTS

如果我改为将表格声明为

CREATE TABLE [dbo].[Hoerses]
(
   [HoersId] INT NOT NULL PRIMARY KEY,
   [DatePurchased] datetime NOT NULL CONSTRAINT [DF_Hoerses_DatePurchased] DEFAULT '1985-01-01'
) 

然后SqlPackage.exe不再尝试删除&重新添加约束。

答案 1 :(得分:1)

Dacpac部署的工作原理是将Database模式的XML结构与VS项目中的结构进行比较。 有时,这个过程会被语法细节混淆,从而导致重复的变化,例如您所描述的。 我的建议是你去一个已部署的数据库,编写麻烦的对象并将其粘贴到该对象的Visual Studio文件的实现上。这解决了明显的差异,因此部署不再被认为可以改变实施。

答案 2 :(得分:0)

我还找到了一篇对我有帮助的文章。 http://johnnydba.blogspot.com/2015/07/are-your-vs-database-projects-dropping.html

基本上,这是文章中提到的可能的问题:

  1. 某些系统函数在SQL Server中用小写表示,例如getdate()sysutcdatetime()getutcdate()newid()
myDate datetime2 DF_myTable_myDate DEFAULT(getdate()) NOT NULL
  1. 默认约束中的标量数值需要用双括号((0))括起来,但是我注意到字符串值没有。
myBit bit DF_myTable_myBit DEFAULT((0)) NOT NULL
  1. 过滤后的索引和检查约束条件必须括在括号()中,列名必须放在方括号中,并且比较运算符的左右两侧不得有空格。
-- Column check
CONSTRAINT CH_myTable_someCheck CHECK ([myColumn]>(0))
-- Function check
CONSTRAINT CH_myTable_anotherCheck CHECK ([dbo].[someFunc]([myColumn],[myAnotherColumn])=(1))
  1. 某些列必须放在方括号[]