Временно отключите ограничения (MS SQL)
-
09-09-2019 - |
Вопрос
Я ищу способ временно отключить все ограничения базы данных (например, связи с таблицами).
Мне нужно скопировать (используя вставки) таблицы одной базы данных в другую базу данных.Я знаю, что могу достичь этого, выполняя команды в правильном порядке (чтобы не нарушать отношения).
Но было бы проще, если бы я мог временно отключить проверку ограничений и снова включить ее после завершения операции.
Возможно ли это?
Решение
Вы можете отключить FK и проверить ограничения только в SQL 2005+.Видишь ИЗМЕНИТЬ ТАБЛИЦУ
ALTER TABLE foo NOCHECK CONSTRAINT ALL
или
ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column
Первичные ключи и уникальные ограничения нельзя отключить, но это должно быть нормально, если я вас правильно понял.
Другие советы
-- Disable the constraints on a table called tableName:
ALTER TABLE tableName NOCHECK CONSTRAINT ALL
-- Re-enable the constraints on a table called tableName:
ALTER TABLE tableName WITH CHECK CHECK CONSTRAINT ALL
---------------------------------------------------------
-- Disable constraints for all tables:
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'
-- Re-enable constraints for all tables:
EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all'
---------------------------------------------------------
И, если вы хотите убедиться, что вы НЕ разорвали свои отношения и не ввели сирот, после того как вы повторно проверите свои чеки, т.е.
ALTER TABLE foo CHECK CONSTRAINT ALL
или
ALTER TABLE foo CHECK CONSTRAINT FK_something
затем вы можете вернуться и выполнить обновление для любых отмеченных столбцов следующим образом:
UPDATE myUpdatedTable SET someCol = someCol, fkCol = fkCol, etc = etc
И любые ошибки на этом этапе будут вызваны несоблюдением ограничений.
На самом деле вы можете отключить все ограничения базы данных одной командой SQL и повторно включить их, вызвав другую единственную команду.Видишь:
В настоящее время я работаю с SQL Server 2005, но я почти уверен, что этот подход работал и с SQL 2000
Отключение и включение Всех Внешних ключей
CREATE PROCEDURE pr_Disable_Triggers_v2
@disable BIT = 1
AS
DECLARE @sql VARCHAR(500)
, @tableName VARCHAR(128)
, @tableSchema VARCHAR(128)
-- List of all tables
DECLARE triggerCursor CURSOR FOR
SELECT t.TABLE_NAME AS TableName
, t.TABLE_SCHEMA AS TableSchema
FROM INFORMATION_SCHEMA.TABLES t
ORDER BY t.TABLE_NAME, t.TABLE_SCHEMA
OPEN triggerCursor
FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema
WHILE ( @@FETCH_STATUS = 0 )
BEGIN
SET @sql = 'ALTER TABLE ' + @tableSchema + '.[' + @tableName + '] '
IF @disable = 1
SET @sql = @sql + ' DISABLE TRIGGER ALL'
ELSE
SET @sql = @sql + ' ENABLE TRIGGER ALL'
PRINT 'Executing Statement - ' + @sql
EXECUTE ( @sql )
FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema
END
CLOSE triggerCursor
DEALLOCATE triggerCursor
Сначала курсор foreignKeyCursor объявляется как оператор SELECT который собирает список внешних ключей и имена их таблиц.Затем открывается курсор и выполняется начальная инструкция FETCH.Этот Оператор ВЫБОРКИ будет считывать данные из первой строки в локальную переменные @foreignKeyName и @tableName.При циклическом перемещении по курсору вы можете проверить @@FETCH_STATUS на наличие значения 0, которое указывает, что выборка прошла успешно.Это означает, что цикл будет продолжать двигаться вперед, чтобы он мог получать каждый последующий внешний ключ из набора строк.@Функция @ @ fetch_status доступны все курсоры на связи.Поэтому, если вы перебираете несколько курсоров, важно проверить значение @@FETCH_STATUS в инструкции сразу после инструкции FETCH.@@FETCH_STATUS будет отражать статус самой последней операции выборки в соединении.Допустимыми значениями для @@FETCH_STATUS являются:
0 = ВЫБОРКА прошла успешно
-1 = ВЫБОРКА была неудачной
-2 = строка, которая была извлечена, отсутствуетВнутри цикла код создает команду ALTER TABLE по-разному в зависимости от того, предполагается ли отключить или включить ограничение внешнего ключа (с использованием ключевого слова CHECK или NOCHECK).Инструкция затем печатается в виде сообщения, чтобы можно было наблюдать за ее ходом, а затем выполняется инструкция .Наконец, когда все строки будут повторены до конца, хранимая процедура закрывается и освобождает курсор.