Временно отключить ограничения (MS SQL)
Я ищу способ временно отключить все ограничения БД (например, отношения таблиц).
Мне нужно скопировать (используя вставки) таблицы одной БД в другую БД. Я знаю, что могу достичь этого, выполняя команды в правильном порядке (чтобы не нарушать отношения).
но было бы проще, если бы я мог временно отключить проверку ограничений и включить его после завершения операции.
это возможно?
5 ответов
вы можете отключить FK и проверить ограничения только в SQL 2005+. См.ALTER TABLE
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!--1-->
отключение и включение всех внешних ключей
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. Этот Оператор FETCH считывает данные первой строки в локальную переменные @foreignKeyName и @tableName. После перехода через курсор, вы можете проверить @@FETCH_STATUS для значение 0, что указывает, что выборка прошла успешно. Это означает, что цикл будет продолжайте двигаться вперед, чтобы получить каждый последующий внешний ключ из набора строк. @@FETCH_STATUS доступен для всех курсоров на соединение. Поэтому, если вы проходите через несколько курсоров, это важно проверить значение @@FETCH_STATUS в инструкции сразу после инструкции FETCH. @Функция @ @ fetch_status будет отражать состояние последней операции выборки на соединение. Допустимые значения для @@FETCH_STATUS:
0 = выборка прошла успешно
-1 = выборка не удалась
-2 = строка, которая была извлечена, отсутствуетвнутри цикла код создает команду ALTER TABLE по-разному в зависимости от того, является ли намерение отключить или включить иностранный ограничение ключа (с помощью ключевого слова CHECK или NOCHECK). Заявление после этого напечатанный как сообщение поэтому свой прогресс можно наблюдать и после этого инструкция выполняется. Наконец, когда все строки были повторены через хранимая процедура закрывает курсор и освобождает его.
посмотреть отключение ограничений и триггеров из журнала MSDN