Я пытаюсь обновить базу данных, которая поддерживается и развертывается с использованием проекта базы данных (.sqlproj
) в Visual Studio 2012. Это проще с SQL Server Management Studio, но в этом случае я должен использовать DACPAC.Как обновить столбец с нулевым значением, который не может быть нулевым, в SQL Server с использованием DACPAC
Каков правильный способ изменения столбца, чтобы он не мог быть нулевым, с использованием DACPAC и без риска потери данных?
В таблицу была добавлена нулевая колонка. Теперь мне нужно опубликовать обновление, которое устанавливает столбец не null и устанавливает значение по умолчанию. Поскольку в таблице есть строки, обновление не выполняется. Существует параметр «разрешить потерю данных», но это не вариант для нас, и это обновление не должно приводить к потере данных. Вот простой пример, который показывает проблему:
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
Эта попытка опубликовать также не удается, с тем же ошибка. Глядя на автоматически генерируется публиковать сценарий, понятно, почему, но это кажется неправильным поведением.
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