Ошибка исключения SQL # 547 и нарушения ограничений внешнего ключа при попытке удаления

#sql-server

#sql-server

Вопрос:

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

Код изначально искал определенный текст в сообщении, а не использовал номер ошибки.

Для обеспечения поддержки нескольких языков было бы лучше перехватывать исключение на основе номера ошибки, а не сообщения об ошибке.

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

  1. Оператор DELETE конфликтовал с ограничением ССЫЛКИ…
  2. Оператор DELETE конфликтовал с ТЕМ же ограничением ссылки на ТАБЛИЦУ…

Можно ли с уверенностью предположить, что оба сообщения об ошибках будут иметь номер ошибки 547? Приветствую Колина

Ответ №1:

547 — это код ошибки, используемый для любого нарушения ограничений, а не только для внешних ключей, например:

 create table T (
    ID int not null,
    constraint CK_Not1 CHECK (ID != 1)
)
go
insert into T (ID) values (2)
go
update T set ID = 1


(1 row(s) affected)
Msg 547, Level 16, State 0, Line 1
The UPDATE statement conflicted with the CHECK constraint "CK_Not1". The conflict occurred in database "Flange", table "dbo.T", column 'ID'.
The statement has been terminated.
  

При этом я не могу придумать какой-либо другой тип ограничения, кроме внешнего ключа, который мог бы быть нарушен с помощью DELETE инструкции. (Подсказка для @onedaywhen)


Если вы заглянете sys.messages , вы увидите, что 547 должно быть для нарушения ограничений:

 select text from sys.messages where message_id=547 and language_id=1033
  

Оператор %ls конфликтовал с ограничением %ls «%.*ls». Конфликт произошел в базе данных «%.*ls», таблице «%.*ls»%ls%.*ls%ls.

Комментарии:

1. «Я не могу придумать какой-либо другой тип ограничения, кроме внешнего ключа, который мог бы быть нарушен с помощью инструкции DELETE» — смотрите Мой ответ.

2. Вы говорите о любом нарушении ограничений, но как насчет 2627? Это уникальное нарушение ограничений, не так ли? Хотя это не было бы нарушено DELETE . Я думаю, вы имеете в виду любое нарушение ограничений проверки .

Ответ №2:

Damien_The_Unbelieve: Я не могу придумать какой-либо другой тип ограничения, кроме внешнего ключа, который мог бы быть нарушен оператором DELETE.

Вот еще:

 CREATE TABLE T1 (ID INTEGER NOT NULL UNIQUE);
CREATE TABLE T2 
(
 ID INTEGER DEFAULT 0 NOT NULL 
 REFERENCES T1 (ID) ON DELETE SET DEFAULT
 CONSTRAINT cannot_be_zero CHECK (ID <> 0)
);
INSERT INTO T1 (ID) VALUES (1);
INSERT INTO T2 (ID) VALUES (1);
DELETE FROM T1;
  

Генерирует ошибку:

Сообщение 547, уровень 16, состояние 0, строка 5 Оператор DELETE конфликтовал с КОНТРОЛЬНЫМ ограничением «cannot_be_zero».

Комментарии:

1. приятно — я постараюсь запомнить это в будущем