Временное отключение ограничений (MS SQL)
Я ищу способ временно отключить все ограничения DB (например, отношения таблицы).
Мне нужно скопировать (используя INSERT) одну таблицу DB в другую БД.
Я знаю, что могу добиться этого, выполняя команды в правильном порядке (чтобы не разорвать отношения).
Но было бы проще, если бы я мог временно отключить проверку ограничений и снова включить его после завершения операции.
Возможно ли это?
Ответы
Ответ 1
Вы можете отключить ограничения FK и CHECK только в SQL 2005 +. См. ALTER TABLE
ALTER TABLE foo NOCHECK CONSTRAINT ALL
или
ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column
Первичные ключи и уникальные ограничения не могут быть отключены, но это должно быть ОК, если я понял вас правильно.
Ответ 2
-- 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'
---------------------------------------------------------
Ответ 3
И если вы хотите проверить, что вы НЕ нарушили ваши отношения и внесли сирот, как только вы повторно вооружили свои чеки, то есть
ALTER TABLE foo CHECK CONSTRAINT ALL
или
ALTER TABLE foo CHECK CONSTRAINT FK_something
то вы можете вернуться в систему и выполнить обновление по любым проверенным столбцам:
UPDATE myUpdatedTable SET someCol = someCol, fkCol = fkCol, etc = etc
И любые ошибки в этой точке будут связаны с невыполнением ограничений.
Ответ 4
Фактически вы можете отключить все ограничения базы данных в одной команде SQL и снова включить их при вызове другой отдельной команды. См:
В настоящее время я работаю с SQL Server 2005, но я почти уверен, что этот подход также работал с SQL 2000
Ответ 5
Отключение и включение всех внешних ключей
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 в соединении. Допустимыми значениями для @@FETCH_STATUS являются:
0 = FETCH был успешным
-1 = FETCH не увенчался успехом
-2 = строка, которая была извлечена, отсутствует
Внутри цикла код генерирует команду ALTER TABLE по-разному в зависимости от того, является ли намерение отключить или разрешить иностранные ключевое ограничение (используя ключевое слово CHECK или NOCHECK). Утверждение затем печатается как сообщение, чтобы можно было наблюдать его прогресс, а затем выполняется. Наконец, когда все строки были повторены через, хранимая процедура закрывает и освобождает курсор.
см. Отключение ограничений и триггеров из журнала MSDN