ALTER TABLE с программно определенным постоянным значением DEFAULT - PullRequest
6 голосов
/ 18 марта 2009

Я пытаюсь добавить столбец (MSSQL 2005) в таблицу (Сотрудник) с ограничением по умолчанию для первичного ключа другой таблицы (Отдел). Затем я собираюсь сделать этот столбец 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

Базы данных Production, Test и Development вышли из синхронизации, и DepartmentID для DepartmentName = "RocketScience" может совпадать или не совпадать, поэтому я не хочу просто говорить DEFAULT (somenumber). Я продолжаю получать «Переменные недопустимы в операторе ALTER TABLE», независимо от того, каким образом я атакую ​​проблему.
Как правильно это сделать? Я также попытался вложить оператор SELECT, который получает «Подзапросы не разрешены в этом контексте. Допускаются только скалярные выражения ».

Кроме того, что было бы действительно здорово, я мог бы заполнить значения столбца одним оператором вместо выполнения

{ALTER null}
{Update values}
{ALTER not null}

шагов. Я прочитал что-то о команде WITH VALUES, но не смог заставить ее работать. Спасибо !!!

Ответы [ 3 ]

8 голосов
/ 19 марта 2009

Принятый ответ работал отлично (спасибо marc_s), но после того, как я некоторое время думал об этом, я решил пойти другим путем.
В основном потому, что на сервере должна остаться функция, которая, как мне кажется, в конечном итоге вызывается каждый раз, когда добавляется сотрудник.
Если кто-то напутает с этой функцией позже, никто не сможет ввести сотрудника, и причина не будет очевидной. (Даже если это не так, на сервере все еще есть дополнительные функции, которые там не обязательно)

Я динамически собирал команду в переменную и затем вызывал ее с помощью команды EXECUTE.

Не только это, но так как я использовал ключевое слово DEFAULT с 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
7 голосов
/ 18 марта 2009

Вы можете заключить код, чтобы найти свой идентификатор отдела в сохраненной функции и использовать его в своем выражении ограничения DEFAULT:

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())

Это помогает?

Марк

3 голосов
/ 20 октября 2016

Если вы примените ограничение внешнего ключа после добавления столбца, вы можете использовать любое значение для значения по умолчанию при изменении таблицы. Затем вы можете запустить оператор обновления со значением вашей переменной.

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;
...