Временно отключите ограничения (MS SQL) - PullRequest
193 голосов
/ 10 апреля 2009

Я ищу способ временно отключить все ограничения БД (например, табличные отношения).

Мне нужно скопировать (используя INSERT) таблицы одной БД в другую БД. Я знаю, что могу добиться этого, выполняя команды в правильном порядке (чтобы не нарушать отношения).

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

Возможно ли это?

Ответы [ 5 ]

205 голосов
/ 10 апреля 2009

Вы можете отключить ограничения FK и CHECK только в SQL 2005 + . См. ALTER TABLE

ALTER TABLE foo NOCHECK CONSTRAINT ALL

или

ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column

Первичные ключи и уникальные ограничения не могут быть отключены, но это должно быть нормально, если я вас правильно понял.

192 голосов
/ 24 октября 2014
-- 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'
---------------------------------------------------------
57 голосов
/ 10 апреля 2009

И, если вы хотите проверить, что вы не нарушили ваши отношения и не представили сирот, после того, как вы перевооружили свои чеки, т.е.

ALTER TABLE foo CHECK CONSTRAINT ALL

или

ALTER TABLE foo CHECK CONSTRAINT FK_something

, затем вы можете запустить и выполнить обновление для всех отмеченных столбцов, например:

UPDATE myUpdatedTable SET someCol = someCol, fkCol = fkCol, etc = etc

И любые ошибки в этой точке будут вызваны несоблюдением ограничений.

16 голосов
/ 21 апреля 2009

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

В настоящее время я работаю с SQL Server 2005, но я почти уверен, что этот подход также работал с SQL 2000

2 голосов
/ 12 ноября 2009

Отключение и включение всех внешних ключей

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

...