Невозможно удалить или изменить или просмотреть ограничение внешнего ключа той же таблицы - PullRequest
3 голосов
/ 19 августа 2011

Такое же ограничение внешнего ключа таблицы в моей базе данных недоступно. Я не могу его уронить, отключить, добавить обратно, ... Как мне удалить и заново добавить?

Примечание. У меня несколько версий базы данных, созданных с использованием одного и того же сценария. Только в одном я вижу это поведение. В других случаях этот ключ легко добавляется и удаляется.

Большое спасибо. Вот несколько скриптов, которые я запустил, и результат:

В какой-то момент в прошлом я запускал следующий скрипт:

ALTER TABLE Recipe
ADD CONSTRAINT FK_Recipe_DuplicateOfRecipeId_Recipe_Id FOREIGN KEY (DuplicateOfRecipeId)
    REFERENCES Recipe (Id) ;

сейчас работает

ALTER TABLE Recipe DROP CONSTRAINT  FK_Recipe_DuplicateOfRecipeId_Recipe_Id 
results in the following error:
'FK_Recipe_DuplicateOfRecipeId_Recipe_Id' is not a constraint.

и работает

ALTER TABLE Recipe NOCHECK CONSTRAINT FK_Recipe_DuplicateOfRecipeId_Recipe_Id
results in: Constraint 'FK_Recipe_DuplicateOfRecipeId_Recipe_Id' does not exist.

так что я бегу

alter table Recipe ADD CONSTRAINT FK_Recipe_DuplicateOfRecipeId_Recipe_Id FOREIGN KEY (DuplicateOfRecipeId) REFERENCES Recipe (Id);

и я получаю:

The ALTER TABLE statement conflicted with the FOREIGN KEY SAME TABLE constraint "FK_Recipe_DuplicateOfRecipeId_Recipe_Id". The conflict occurred in database "CrawlerDB", table "dbo.Recipe", column 'Id'.

так что я бегу:

select COUNT(*) from sys.objects where name = 'FK_Recipe_DuplicateOfRecipeId_Recipe_Id'
select COUNT(*) from sys.all_objects where name = 'FK_Recipe_DuplicateOfRecipeId_Recipe_Id'
SELECT COUNT(*) FROM sys.foreign_keys where name = 'FK_Recipe_DuplicateOfRecipeId_Recipe_Id'

и все 3 ничего не возвращают.

Что происходит и как мне это исправить? Мне нужно получить доступ к этому объекту, удалить его и добавить обратно.
Большое спасибо!

Ответы [ 2 ]

2 голосов
/ 22 августа 2011

Я предполагаю, что ваша основная база данных повреждена.Возможно, вам лучше всего подойдет , перестроив его .

Однако в качестве обходного пути вы можете попробовать это:

  1. Дублируйте ваш внешний ключв столбец без FK

    ALTER TABLE Recipe ADD DuplicateOfFK INT

  2. Скопируйте все данные FK в дубликат

    UPDATE Recipe SET DuplicateOfFK = DuplicateOfRecipeId

  3. Отбросьте столбец «Внешний ключ»

    ALTER TABLE Recipe DROP COLUMN DuplicateOfRecipeId

  4. Назад.

    ALTER TABLE Recipe ADD DuplicateOfRecipeId INT

    UPDATE Recipe SET DuplicateOfRecipeId = DuplicateOfFK

    ALTER TABLE Recipe DROP COLUMN DuplicateOfFK

  5. Добавить ограничение обратно.

0 голосов
/ 14 января 2014

Ваш комментарий выше должен был дать вам подсказку:

после установки всех значений в поле внешнего ключа на ноль, тогда все работает снова.Но почему?

К сожалению, сообщение об ошибке может вводить в заблуждение.Оператор, добавляющий внешний ключ назад, не удался не потому, что вы создавали циклическую ссылку, а потому, что DuplicateOfRecipeId содержал как минимум одно ненулевое значение, которое еще не содержалось в Id.работает:

create table dbo.Recipe
(
    Id int not null identity(1, 1)
        constraint PK_Recipe primary key nonclustered
    , DuplicateOfRecipeId int not null
);
insert dbo.Recipe values (1), (2), (3);
alter table Recipe add constraint FK_Recipe_DuplicateOfRecipeId_Recipe_Id foreign key (DuplicateOfRecipeId) references Recipe (Id);
drop table dbo.Recipe
go

Но следующий код не работает (обратите внимание на различные значения DuplicateOfRecipeId):

create table dbo.Recipe
(
    Id int not null identity(1, 1)
        constraint PK_Recipe primary key nonclustered
    , DuplicateOfRecipeId int not null
);
insert dbo.Recipe values (4), (5), (6);
alter table Recipe add constraint FK_Recipe_DuplicateOfRecipeId_Recipe_Id foreign key (DuplicateOfRecipeId) references Recipe (Id);
drop table dbo.Recipe
go
...