ИЗМЕНИТЬ ТАБЛИЦУ с программно определенным постоянным значением по УМОЛЧАНИЮ
-
20-08-2019 - |
Вопрос
Я пытаюсь добавить столбец (MSSQL 2005) в таблицу (Employee) с ограничением по умолчанию первичного ключа другой таблицы (Department).Затем я собираюсь сделать этот столбец FK для этой таблицы.По сути, это приведет к назначению новых сотрудников в базовый отдел на основе названия отдела, если идентификатор отдела не указан.
Это не сработает:
DECLARE @ErrorVar INT
DECLARE @DepartmentID INT
SELECT @DepartmentID = DepartmentID
FROM Department
WHERE RealName = 'RocketScience'
ALTER TABLE [Employee]
ADD [DepartmentID] INT NULL
CONSTRAINT [DepartmentIDOfAssociate] DEFAULT (@DepartmentIDAssociate)
SELECT @ErrorVar = @@Error
IF (@ErrorVar <> 0)
BEGIN
GOTO FATAL_EXIT
END
Базы данных производства, тестирования и разработки перестали синхронизироваться, и DepartmentID для DepartmentName = ‘RocketScience’ может совпадать, а может и не совпадать, поэтому я не хочу просто говорить DEFAULT (somenumber).Я продолжаю получать сообщение “Переменные не разрешены в операторе ALTER TABLE”, независимо от того, каким способом я решаю проблему.
Каков правильный способ сделать это?Я также попытался вложить оператор select, который выдает “Подзапросы не разрешены в этом контексте.Разрешены только скалярные выражения.”
Кроме того, что было бы действительно здорово, я мог бы заполнить значения столбцов в одном операторе вместо того, чтобы выполнять
{ИЗМЕНИТЬ значение null}
{Обновить значения}
{ИЗМЕНИТЬ значение not null}
шаги.Я кое-что читал о команде WITH VALUES, но не смог заставить ее работать.Спасибо!!!
Решение
Вы могли бы обернуть код для поиска идентификатора вашего отдела в сохраненную функцию и использовать его в вашем операторе ограничения ПО УМОЛЧАНИЮ:
CREATE FUNCTION dbo.GetDepartment()
RETURNS INT
AS
BEGIN
DECLARE @DepartmentID INT
SELECT @DepartmentID = DepartmentID
FROM Department
WHERE RealName = 'RocketScience'
RETURN @DepartmentID
END
А потом:
ALTER TABLE [Employee]
ADD [DepartmentID] INT NULL
CONSTRAINT [DepartmentIDOfAssociate] DEFAULT (dbo.GetDepartment())
Помогает ли это?
Марк
Другие советы
Принятый ответ отлично сработал (спасибо marc_s), но после того, как я немного подумал об этом, я решил пойти другим путем.
Главным образом потому, что на сервере должна быть оставлена функция, которая, я думаю, в конечном итоге вызывается каждый раз, когда добавляется сотрудник.
Если бы кто-то испортил функцию позже, то никто не смог бы ввести сотрудника, и причина была бы неочевидна.(Даже если это не так, то на сервере все еще есть дополнительные функции, которые там не нужны)
Что я сделал, так это динамически собрал команду в переменную, а затем вызвал ее с помощью команды EXECUTE .
Не только это, но поскольку я использовал ключевое слово ПО УМОЛЧАНИЮ с NOT NULL, таблица была снова заполнена, и мне не пришлось запускать несколько команд, чтобы это сделать.Я нашел это по счастливой случайности...
DECLARE @ErrorVar INT
DECLARE @DepartmentIDRocketScience INT
DECLARE @ExecuteString NVARCHAR(MAX)
SELECT @DepartmentIDRocketScience = DepartmentID
FROM Department
WHERE RealName = 'RocketScience'
SET @ExecuteString = ''
SET @ExecuteString = @ExecuteString + 'ALTER TABLE [Employee] '
SET @ExecuteString = @ExecuteString + 'ADD [DepartmentID] INT NOT NULL '
SET @ExecuteString = @ExecuteString + 'CONSTRAINT [DF_DepartmentID_RocketScienceDepartmentID] DEFAULT ' +CAST(@DepartmentIDAssociate AS NVARCHAR(MAX))
EXECUTE (@ExecuteString)
SELECT @ErrorVar = @@Error
IF (@ErrorVar <> 0)
BEGIN
GOTO FATAL_EXIT
END
Если вы примените ограничение внешнего ключа после добавления столбца, вы можете использовать любое значение по умолчанию при изменении таблицы.Затем вы можете запустить инструкцию update со значением вашей переменной.
ALTER TABLE Employee
ADD DepartmentID INT NOT NULL
Default -1;
UPDATE Employee
SET Employee.DepartmentID = @DepartmentID
WHERE DepartmentID = -1;
ALTER TABLE Employee
ADD CONSTRAINT fk_employee_to_department FOREIGN KEY (DepartmentID)
REFERENCES Department;