sql-server - 如何在 SQL Server 中使用 DACPAC 将可空列更新为不可空列

标签 sql-server visual-studio-2012 sql-server-2012 dacpac

我正在尝试更新使用 Visual Studio 2012 中的数据库项目 (.sqlproj) 维护和部署的数据库。使用 SQL Server Management Studio 更容易,但在本例中我必须使用 DACPAC 进行部署。

使用 DACPAC 将列更改为不可空且不存在数据丢失风险的正确方法是什么?

表中添加了可为空的列。现在我需要发布一个更新,将列设置为非空并设置默认值。因为表中有行,所以更新失败。有一个设置“允许数据丢失”,但这对我们来说不是一个选项,并且此更新不应导致数据丢失。这是一个显示问题的简单示例:

CREATE TABLE [dbo].[Hello]
(
    [Id] INT IDENTITY(100,1) NOT NULL PRIMARY KEY, 
    [HelloString] NVARCHAR(50) NULL , 
    [Language] NCHAR(2) NOT NULL
)

现在发布该数据库并添加行,至少有一行的 HelloString 应该为空。

将表定义更改为:

CREATE TABLE [dbo].[Hello]
(
    [Id] INT IDENTITY(100,1) NOT NULL PRIMARY KEY, 
    [HelloString] NVARCHAR(50) NOT NULL DEFAULT 'Hello' , 
    [Language] NCHAR(2) NOT NULL
)

此内容无法发布。

错误:

Rows were detected. The schema update is terminating because data loss might occur.

接下来,我尝试添加预部署脚本以将所有 NULL 设置为“Hello”:

UPDATE Hello SET HelloString = 'Hello' WHERE HelloString IS NULL

此发布尝试也失败,并出现相同的错误。查看自动生成发布脚本,原因很清楚,但这似乎是不正确的行为。

  1. 在添加默认值之前应用NOT NULL更改
  2. 脚本会检查任何行,无论是否有 是否为空。

评论中的建议(为了避免此问题,您必须为所有行向此列添加值)并不能解决此问题。

/*
The column HelloString on table [dbo].[Hello] must be changed from NULL to NOT NULL. If the table contains data, the ALTER script may not work. To avoid this issue, you must add values to this column for all rows or mark it as allowing NULL values, or enable the generation of smart-defaults as a deployment option.
*/

IF EXISTS (select top 1 1 from [dbo].[Hello])
    RAISERROR (N'Rows were detected. The schema update is terminating because data loss might occur.', 16, 127) WITH NOWAIT
GO

PRINT N'Altering [dbo].[Hello]...';
GO

ALTER TABLE [dbo].[Hello] ALTER COLUMN [HelloString] NVARCHAR (50) NOT NULL;
GO

PRINT N'Creating Default Constraint on [dbo].[Hello]....';
GO

ALTER TABLE [dbo].[Hello] 
ADD DEFAULT 'hello' FOR [HelloString];

在 SQL Server 2012 (v11.0.5343)、SQL Server Data Tools 11.1.31009.1 中可见

最佳答案

使用 SSMS 发布 dacpac 时,您将无法访问从 SqlPackage.exe 或 Visual Studio 发布时可用的全套发布选项。我建议使用 SqlPackage.exe 或 Visual Studio 进行发布,并启用“生成智能默认值(如果适用)”选项。对于 SqlPackage.exe,您将运行如下命令:

"C:\Program Files (x86)\Microsoft SQL Server\120\DAC\bin\SqlPackage.exe" /a:publish /sf:"C:\MyDacpac.dacpac" /tcs:"Data Source=MYSERVER;Initial Catalog=MYDATABASE;Integrated Security=true" /p:GenerateSmartDefaults=true

对于 Visual Studio,您需要在“高级发布选项”对话框中选中“生成智能默认值”选项。

关于sql-server - 如何在 SQL Server 中使用 DACPAC 将可空列更新为不可空列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32101913/

相关文章:

sql - 创建 SQL 脚本以将旧数据库更改为当前数据库

visual-studio-2012 - 从 VS2012 运行 SSIS 包时出现 IsVisualStudio2012ProInstalled() 方法未找到错误

c# - 将 ViewModel 中包含的 ObservableCollection 绑定(bind)到 ListView

sql-server - 了解 SQL Server 审计和 .sqlaudit 日志文件

sql - 如何显示两个日期之间的小时和分钟

sql - 窗口函数 - 带重置的运行总计

sql-server - 使用 SQL Server 作为 Orleans 存储

sql-server - 计算每组的差异总和

c# - 使用 Office 应用程序简单查询数据库?

c++ - 从类节点上的结构中创建二叉搜索树会很糟糕吗?