我试图更新在Visual Studio 2012中使用数据库项目(.sqlproj
)维护和部署的数据库。使用SQL更容易Server Management Studio,但在这种情况下,我必须使用DACPAC进行部署。我如何更新一个可空的列不可为空,在SQL Server中使用DACPAC
使用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是“你好”:
UPDATE Hello SET HelloString = 'Hello' WHERE HelloString IS NULL
此发布尝试也失败,与同错误。看着自动生成发布脚本很明显为什么,但这似乎是不正确的行为。
- 前的默认添加
- 脚本检查任何行,则应用
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数据工具11.1.31009.1
你可以插入默认值到空字段然后做更新? –
@HolmesIV我试图用预部署脚本来做到这一点,但我会尝试单独执行它,看看是否有所作为。谢谢! – mafue