Составной внешний ключ с обнуляемым столбцом - PullRequest
4 голосов
/ 13 октября 2010

В следующей таблице есть ли способ гарантировать, что PreviousID всегда ссылается на идентификатор в строке с совпадающим ParentID, или, если ParentID равен нулю, он также равен нулю в указанной строке?

CREATE TABLE MyTable (
  ID int not null identity(1,1) primary key,
  ParentID int null foreign key references MyTable (ID),
  PreviousID int null foreign key reference MyTable (ID),
    foreign key (ParentID, PreviousID) references MyTable (ParentID, ID)
)

Пример:

+-ID-+-ParentID-+-PreviousID-+  
|  1 |   NULL   |    NULL    |  
|  2 |     1    |    NULL    |  
|  3 |   NULL   |      2     | <-- shouldn't be possible, should have to refer to ID where ParentID is null
+----+----------+------------+  

Есть ли способ применить это?

ОБНОВЛЕНИЕ : Для тех, кому интересно, составной внешний ключ не применяет это дляследующая причина (скопирована из MSDN ):

Ограничение FOREIGN KEY может содержать нулевые значения;однако, если какой-либо столбец составного ограничения FOREIGN KEY содержит нулевые значения, проверка всех значений, составляющих ограничение FOREIGN KEY, пропускается.Чтобы убедиться, что все значения составного ограничения FOREIGN KEY проверены, укажите NOT NULL для всех участвующих столбцов.

UPDATE : в случае, если это помогает визуализировать структуру данныхбудучи представленным, это B-дерево, где узлы, имеющие одного и того же родителя, составляют связанный список.Я пытаюсь обеспечить, чтобы каждый «предыдущий» указатель в связанном списке указывал на другой узел с тем же родителем.В случае, если родительский элемент является нулевым, он должен указывать на другой узел, где родительский элемент также является нулевым.

1 Ответ

0 голосов
/ 13 октября 2010

Попробуйте:

CREATE TABLE MyTable ( 
  ID int not null identity(1,1) primary key, 
  ParentID int null foreign key references MyTable (ID), 
  PreviousID int null foreign key references MyTable (ID), 
    foreign key (ParentID, PreviousID) references MyTable (ParentID, ID),
    unique (ParentID, ID),  /* Required for foreign key */
  check (PreviousID is null or ParentID is not null)  /* enforeces requested constraint */
) 

Результаты:

insert into MyTable (ParentID, PreviousID) values (null, null) /* (1 row(s) affected) */
insert into MyTable (ParentID, PreviousID) values (1, null) /* (1 row(s) affected) */
insert into MyTable (ParentID, PreviousID) values (null, 2) /* The INSERT statement conflicted with the CHECK constraint. 
    The statement has been terminated. */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...