Каждую неделю мой клиент отправляет мне базу данных с очень большой таблицей без первичного ключа, и столбец с уникальным идентификатором в ней обнуляется.
Поэтому я запускаю ALTER TABLE
, чтобы установить столбец Я хочу в качестве первичного ключа NOT NULL:
ALTER TABLE Live1.dbo.Orders
ALTER COLUMN OrderID varchar(10) NOT NULL;
Затем, через 45 минут, и я добавляю свой первичный ключ:
ALTER TABLE Live1.dbo.Orders
ADD CONSTRAINT PK_OrdersOrderID PRIMARY KEY CLUSTERED (OrderID)
Пока все отлично и замечательно.
До этого я пытаюсь автоматизировать эту долгую и утомительную операцию.
Я создал очень простую хранимую процедуру, которая запускается, как только база данных моего клиента завершается, как часть процесса восстановления. Задание агента:
CREATE PROCEDURE dbo.AddPKey
AS
BEGIN
SET NOCOUNT ON;
ALTER TABLE Live1.dbo.Orders ALTER COLUMN OrderID varchar(10) NOT NULL;
ALTER TABLE Live1.dbo.Orders ADD CONSTRAINT PK_OrdersOrderID PRIMARY KEY CLUSTERED (OrderID)
END
GO
Сбой через 1 секунду с сообщением об ошибке:
Невозможно определить ограничение PRIMARY KEY для столбца с нулевым значением в таблице «Заказы». [SQLSTATE 42000] (Ошибка 8111) Не удалось создать ограничение или индекс. Смотрите предыдущие ошибки. [SQLSTATE 42000] (Ошибка 1750). Шаг не выполнен.
Таким образом, он пытается установить ограничение первичного ключа до завершения предыдущего шага ALTER COLUMN
. Должно пройти не менее 45 минут, прежде чем он попытается добавить ограничение первичного ключа, но он попытается сделать это сразу. Если я запускаю ALTER COLUMN
вручную, он работает просто отлично.
Что дает? Я написал десятки хранимых процедур, и ни одна из них не ведет себя так?
Что я могу сделать, чтобы заставить его ждать? Я думал, что это то, что сделала точка с запятой в конце строки ALTER COLUMN
?
ОБНОВЛЕНИЕ:
Большое спасибо π за проницательный ответ и разъяснение того, что на самом деле здесь происходит. Мой последний сохраненный pro c выглядит так:
DECLARE @DynamicSQL nvarchar(4000)
ALTER TABLE Live1.dbo.Orders ALTER COLUMN OrderID varchar(10) NOT NULL;
SET @DynamicSQL = 'ALTER TABLE Live1.dbo.Orders
ADD CONSTRAINT PK_OrdersOrderID PRIMARY KEY CLUSTERED (OrderID);'
EXEC Live1.sys.sp_executesql @DynamicSQL
, который работает без ошибок:)