9

我正在尝试更新使用 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
)

这不能发布。

错误:

检测到行。架构更新正在终止,因为可能会发生数据丢失。

接下来,我尝试添加一个预部署脚本以将所有 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

4

1 回答 1

8

使用 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,您将在“高级发布选项”对话框中选中“生成智能默认值”选项。

于 2015-08-19T18:59:41.367 回答