DACPAC前期脚本是什么?

问题描述 投票:0回答:1

我在发布DACPAC时遇到一个问题。(SQL 2012)我在生产中的表有null,非null值列,我需要让这个列不能为null,并删除另一个列,因为这可能不会在应用程序中使用。

我试着用部署前的脚本更新null列的值,改变列和删除列,但得到错误-"检测到行。模式更新正在终止,因为可能会发生数据丢失。"

由于这是一个敏感的生产,我不想取消选中发布选项'Block incremental deploymentif data loss might occur'。

如果有人有什么办法,请告诉我。

sql-server sql-server-2008 visual-studio-code visual-studio-2015 msdeploy
1个回答
0
投票

我们先来了解一下DACPACs是如何部署的,以下是任务的顺序

1.使用*.dacpack文件中的模式建立一个空的DB,称其为 "vNextDB"

2.将生产DB与vNextDB进行对比,并生成一个部署变化的脚本,我们称它为deploy.sql(其实你可以把这个写到一个文件中,然后手动检查,可以看 "SqlPackage.exe "上的文档

3.运行预部署脚本

4.运行步骤(2)中的deploy.sql。

5.运行部署后脚本

如果没有,看看deploy.sql脚本生成的时间,它是在预部署脚本执行之前完成的,所以很明显,它确实看到了NULL值,并生成了脚本,从部署中退缩。

如果你让sqlproject.exe把deploy.sql写到磁盘上,然后在文本编辑器中打开,你就可以看到它是如何后退的(我不能说它是如何后退的,因为每个版本的sqlpackage.exe都有不同的做法。他们一直在改进它)。

这里有几个选项

A) 将你的部署分为两个,第一个部署将没有模式的变化,它只是在postpre部署步骤中运行 "UPDATE MyTable SET theColumn = '' WHERE theColumn IS NULL",而第二个部署将有实际的变化。

B) 退一步,全面思考如何处理DB模式的版本化,你应该有一个版本化策略,你应该考虑到向后的兼容性等等。(即你可以引入一个默认值为NOT NULL的新列,DB客户端可以开始使用该列,而无法更新的旧客户端仍然会被支持,因为你没有马上删除旧列)

即使你选择A选项来解决当前的问题,从长远来看,你也应该建立一个版本管理的启动机制。每个自尊的数据存储都有一个版本策略:-),你应该给你的DB一个版本策略。

© www.soinside.com 2019 - 2024. All rights reserved.