Я хотел бы определить ограничение между двумя обнуляемыми FK в таблице, где, если один имеет значение null, другому требуется значение, но оба не могут быть нулевыми, и оба не могут иметь значений. Логика заключается в том, что производная таблица наследует данные от любой из таблиц FK, чтобы определить ее тип. Кроме того, для забавных бонусных очков, это плохая идея?
Добавьте ограничение SQL XOR между двумя FK, допускающими значение NULL.
Ответы (3)
Один из способов добиться этого — просто записать, что на самом деле означает «исключающее ИЛИ»:
CHECK (
(FK1 IS NOT NULL AND FK2 IS NULL)
OR (FK1 IS NULL AND FK2 IS NOT NULL)
)
Однако, если у вас много FK, описанный выше метод может быстро стать громоздким, и в этом случае вы можете сделать что-то вроде этого:
CHECK (
1 = (
(CASE WHEN FK1 IS NULL THEN 0 ELSE 1 END)
+ (CASE WHEN FK2 IS NULL THEN 0 ELSE 1 END)
+ (CASE WHEN FK3 IS NULL THEN 0 ELSE 1 END)
+ (CASE WHEN FK4 IS NULL THEN 0 ELSE 1 END)
...
)
)
Кстати, этот шаблон можно использовать в законных целях, например этот (хотя и неприменим к MS SQL Server из-за отсутствия отложенных ограничений). Является ли это законным в вашем конкретном случае, я не могу судить на основании предоставленной вами информации.
CHECK(fk1 IS NULL != fk2 IS NULL)
- person Stephen Fuhry; 11.01.2015
Вы можете использовать ограничение проверки:
create table #t (
a int,
b int);
alter table #t add constraint c1
check ( coalesce(a, b) is not null and a*b is null );
insert into #t values ( 1,null);
insert into #t values ( null ,null);
Бег:
The INSERT statement conflicted with the CHECK constraint "c1".
coalesce(a, b)
вернет не-NULL, когда оба a
и b
не-NULL, и ПРОВЕРКА будет пройдена, чего не должно быть (OP явно указал, что оба не могут иметь значений). Другими словами, insert into #t values (1, 1)
должен выйти из строя.
- person Branko Dimitrijevic; 21.06.2012
a*b
), которое можно убрать, если вместо него использовать a|b
- person PLopes; 29.06.2020
Альтернативный способ — определить это ограничение проверки в процедуре. Прежде чем вы вставите запись в производную таблицу, ограничение должно быть удовлетворено. В противном случае вставка завершается неудачно или возвращает ошибку.