如何使用 DACPAC 在 SQL 服务器中将可空列更新为不可空列
How can I update a nullable column to be not nullable, in SQL Server using DACPAC
我正在尝试更新使用 Visual Studio 2012 年的数据库项目 (.sqlproj
) 维护和部署的数据库。使用 SQL Server Management Studio 更容易,但在这种情况下,我必须使用 DACPAC 进行部署。
在不冒数据丢失风险的情况下,使用 DACPAC 将列更改为不可空的正确方法是什么?
可空列已添加到 table。现在我需要发布一个更新,将列设置为非空并设置默认值。因为 table 中有行,更新失败。有一个 'allow data loss' 的设置,但这不是我们的选项,此更新不应导致数据丢失。这是一个显示问题的简单示例:
CREATE TABLE [dbo].[Hello]
(
[Id] INT IDENTITY(100,1) NOT NULL PRIMARY KEY,
[HelloString] NVARCHAR(50) NULL ,
[Language] NCHAR(2) NOT NULL
)
现在发布该数据库并添加行,至少有一行的 HelloString 应为 null。
将 table 定义更改为:
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
这次发布尝试也失败了,出现同样的错误。查看 auto generated 发布脚本很清楚为什么,但这似乎是不正确的行为。
- 在添加默认值之前应用
NOT NULL
更改
- 脚本检查任何行,是否有无关紧要
是否为空值。
评论中的建议(为避免此问题,您必须为所有行向此列添加值)无法解决此问题。
/*
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 发布并启用 "Generate smart defaults, where applicable" 选项。在 SqlPackage.exe 的情况下,你会 运行 这样的命令:
"C:\Program Files (x86)\Microsoft SQL Server0\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,您需要在“高级发布选项”对话框中选中“生成智能默认值”选项。
我正在尝试更新使用 Visual Studio 2012 年的数据库项目 (.sqlproj
) 维护和部署的数据库。使用 SQL Server Management Studio 更容易,但在这种情况下,我必须使用 DACPAC 进行部署。
在不冒数据丢失风险的情况下,使用 DACPAC 将列更改为不可空的正确方法是什么?
可空列已添加到 table。现在我需要发布一个更新,将列设置为非空并设置默认值。因为 table 中有行,更新失败。有一个 'allow data loss' 的设置,但这不是我们的选项,此更新不应导致数据丢失。这是一个显示问题的简单示例:
CREATE TABLE [dbo].[Hello]
(
[Id] INT IDENTITY(100,1) NOT NULL PRIMARY KEY,
[HelloString] NVARCHAR(50) NULL ,
[Language] NCHAR(2) NOT NULL
)
现在发布该数据库并添加行,至少有一行的 HelloString 应为 null。
将 table 定义更改为:
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
这次发布尝试也失败了,出现同样的错误。查看 auto generated 发布脚本很清楚为什么,但这似乎是不正确的行为。
- 在添加默认值之前应用
NOT NULL
更改 - 脚本检查任何行,是否有无关紧要 是否为空值。
评论中的建议(为避免此问题,您必须为所有行向此列添加值)无法解决此问题。
/*
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 发布并启用 "Generate smart defaults, where applicable" 选项。在 SqlPackage.exe 的情况下,你会 运行 这样的命令:
"C:\Program Files (x86)\Microsoft SQL Server0\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,您需要在“高级发布选项”对话框中选中“生成智能默认值”选项。