Visual Studio数据库项目 - 在预部署中更改表不起作用

时间:2017-09-07 03:54:16

标签: sql visual-studio-2017 sql-server-2016

我需要在Visual Studio 2017中从数据库项目更改表的复合主键,即在删除所有重复项后将其更改为2列而不是4列。我把删除重复项的脚本放到预部署中,它是这样的:

CREATE TABLE tmp_table
(  
    <same columns as old_table>,
    CONSTRAINT [PK_NewPK] 
        PRIMARY KEY CLUSTERED ([Column1], [Column2] ASC)
) ON [PRIMARY]

INSERT INTO tmp_table 
    (SELECT <unique data from old_table>)

TRUNCATE old_table
DROP old_table

EXEC sp_rename 'tmp_table', 'old_table'

它就像魅力一样,但新的old_table在部署后仍然具有旧的4列主键,这并不奇怪,因为old_table的代码没有被更改。问题是,当我尝试编辑old_table以获得2列PK时,部署失败并带有

  

SQL72014:.Net SqlClient数据提供者:
  Msg 3728,Level 16,State 1,Line 1
  'DF__old_table__'不是约束。

我假设在预部署脚本之后应用对表的代码更改,但是这里的事件顺序看起来非常错误,我看不出如何修复它。

1 个答案:

答案 0 :(得分:0)

好的,在多次重读this post后,我意识到这里的事件顺序出现了什么问题(是的,预部署前阶段问题) - 也就是说,部署代码是从模型比较结果生成的,模型比较是在执行预部署代码之前完成的。所以,它是这样的:

  • 比较源和目标数据库模型,记录old_table的主要密钥更改,并修改部署脚本以反映该情况,包括删除默认约束;
  • 执行预部署代码,它会稍微改变old_table,但部署脚本并不知道;
  • 执行部署代码,并在尝试删除该默认约束时立即崩溃,因为它不再存在(但是当我们检查时它就在那里,只是它不是并且承担了&t; t甚至是......呃);
  • 利润(不是真的)。​​

是的,这就是它应该如何运作,我真的错过了一些明显的东西。现在我知道了。

我的解决方案是在预部署脚本的END处创建DF__old_table__约束,因此当部署代码查找时它仍然存在于更改的old_table中,但随后它会因为部署而消失old_table的代码没有任何默认值,即使这样做,约束也会有不同的名称(因为未命名的约束是邪恶的)。

说到这个,这个解决方案并不是100%可靠,因为未命名的约束不能保证在开发机器和生产服务器上具有相同的随机生成的名称。而且它很丑陋。但它适用于我们的设置,而我能想到的任何替代方案都更加黑客。