#sql-server
#sql-server
Вопрос:
Я просматриваю некоторый код (я его не писал!), чтобы проверить, что наш код улавливает два состояния ошибки при попытке удалить строку таблицы, где существуют зависимости.
Код изначально искал определенный текст в сообщении, а не использовал номер ошибки.
Для обеспечения поддержки нескольких языков было бы лучше перехватывать исключение на основе номера ошибки, а не сообщения об ошибке.
В тесте есть два набора текста, которые ищет код, и я, похоже, не могу определить, в чем разница, поэтому мне неудобно просто проверять номер ошибки 547.
- Оператор DELETE конфликтовал с ограничением ССЫЛКИ…
- Оператор 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.
При этом я не могу придумать какой-либо другой тип ограничения, кроме внешнего ключа, который мог бы быть нарушен с помощью (Подсказка для @onedaywhen) DELETE
инструкции.
Если вы заглянете 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. приятно — я постараюсь запомнить это в будущем