Сложное ограничение внешнего ключа в SQL - PullRequest
3 голосов
/ 10 мая 2011

Есть ли способ определить ограничение с помощью SQL Server 2005, чтобы не только обеспечить наличие внешнего ключа в другой таблице, но и соответствовать определенным критериям?

Например, скажем, у меня есть две таблицы:

Table A
--------
Id - int
FK_BId - int

Table B
--------
Id - int
Name - string
SomeBoolean - bit

Могу ли я определить ограничение, которое говорит, что FK_BId должен указывать на запись в Таблице B, И эта запись в Таблице B должна иметь SomeBoolean = true? Заранее благодарим за любую помощь, которую вы можете предоставить.

Ответы [ 3 ]

4 голосов
/ 11 мая 2011

Вы можете принудительно применить бизнес-правило, используя составной ключ на (Id, SomeBoolean), сослаться на это в таблице A с ограничением CHECK на FK_BSomeBoolean, чтобы убедиться, что оно всегда ИСТИНА. Кстати, я бы рекомендовал избегать BIT и вместо этого использовать CHAR(1) с проверкой домена, например.

CHECK (SomeBoolean IN ('F', 'T'))

Структура таблицы может выглядеть следующим образом:

CREATE TABLE B
(
 Id INTEGER NOT NULL UNIQUE, -- candidate key 1
 Name VARCHAR(20) NOT NULL UNIQUE,  -- candidate key 2
 SomeBoolean CHAR(1) DEFAULT 'F' NOT NULL
    CHECK (SomeBoolean IN ('F', 'T')), 
 UNIQUE (Id, SomeBoolean) -- superkey
); 

CREATE TABLE A 
(
 Ib INTEGER NOT NULL UNIQUE, 
 FK_BId CHAR(1) NOT NULL, 
 FK_BSomeBoolean CHAR(1) DEFAULT 'T' NOT NULL
    CHECK (FK_BSomeBoolean = 'T')
 FOREIGN KEY (FK_BId, FK_BSomeBoolean)
    REFERENCES B (Id, SomeBoolean)
);
2 голосов
/ 10 мая 2011

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

Если это возможно, яЯ бы сказал, что вы бы сделали его составным внешним ключом, используя ID и SomeBoolean, но я не думаю, что на самом деле все равно, какое значение.

0 голосов
/ 10 мая 2011

В некоторых базах данных (я не могу проверить SQL Server) вы можете добавить проверочное ограничение, которое ссылается на другие таблицы.

ALTER TABLE a ADD CONSTRAINT fancy_fk
CHECK (FK_BId IN (SELECT Id FROM b WHERE SomeBoolean));

Я не считаю, что это стандартное поведение.

...