2011-01-17 2 views
4

У меня есть сломанный внешний ключ в SQL Server 2005. Здесь репродукция:Закрепление сломаны внешние ключи с ALTER TABLE ... обратными ПРОВЕРКА ОГРАНИЧЕНИЙ

CREATE TABLE t2(i2 BIGINT NOT NULL PRIMARY KEY) 
CREATE TABLE t1(i1 BIGINT NOT NULL PRIMARY KEY) 

ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (i1) REFERENCES t2 (i2) 
ALTER TABLE t1 NOCHECK CONSTRAINT fk 

INSERT INTO t1 (i1) VALUES (0) 

Если я впоследствии запустить:

ALTER TABLE t1 WITH CHECK CHECK CONSTRAINT fk 

я получаю ошибку:

The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "fk". The conflict occurred in database "broken-fk", table "dbo.t2", column 'i2'.

Я могу это исправить вручную:

DELETE FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t2.i2 = t1.i1) 
ALTER TABLE t1 WITH CHECK CHECK CONSTRAINT fk 

но я бы предпочел сделать это за один шаг, так как каждый, по-видимому, нуждается в сканировании таблицы, а таблица имеет размер в десятки гигабайт.

Возможно ли получить ALTER TABLE, чтобы исправить ошибку (путем удаления строк), а не выйти с ошибкой?

Спасибо.

ответ

4

Is it possible to get the ALTER TABLE to fix the error (by dropping rows) rather than exiting with an error?

Длинные и короткие - нет. Сделайте это в два шага, когда вы знакомы.

Вы можете остановиться на

ALTER TABLE t1 CHECK CONSTRAINT fk 

, который превращает его в новых записях, но оставляет существующие данные в одиночку?

+0

Не тот ответ, на который я надеялся, но спасибо. :) –

+3

Предупреждение о том, что говорят кибервики. В общем случае * не * используйте «ALTER TABLE t1 CHECK CONSTRAINT fk». Всегда используйте ALTER TABLE t1 ** WITH CHECK ** CHECK CONSTRAINT fk, если вы не планируете немедленно отключать и снова устанавливать ограничение. С CHECK имеет огромное значение, поскольку без него ограничение будет отмечено как «не доверенное». Это означает, что оптимизатор будет игнорировать его, а некоторые другие функции могут быть затронуты или отключены (например, некоторые обновления могут не работать). – sqlvogel

+0

@dportas - если вы следуете этому вопросу, и следующее утверждение «оставляет существующие данные в покое», вы увидите, почему WITH CHECK не работает – RichardTheKiwi

Смежные вопросы