7

次の表で、PreviousID が常に ParentID が一致する行の ID を参照するようにする方法はありますか? または、ParentID が null の場合、参照された行でも null になりますか?

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-+-親 ID-+-前の ID-+  
| | 1 | ヌル | ヌル |  
| | 2 | 1 | ヌル |  
| | 3 | ヌル | 2 | <-- 可能ではありません。ParentID が null である ID を参照する必要があります
+----+----------+------------+  

これを強制する方法はありますか?

UPDATE :不思議に思っている人のために、複合外部キーは次の理由でこれを強制しません ( MSDNからコピー):

FOREIGN KEY 制約には null 値を含めることができます。ただし、複合 FOREIGN KEY 制約のいずれかの列に NULL 値が含まれている場合、FOREIGN KEY 制約を構成するすべての値の検証はスキップされます。複合 FOREIGN KEY 制約のすべての値が検証されるようにするには、関係するすべての列で NOT NULL を指定します。

UPDATE : 表現されているデータ構造を視覚化するのに役立つ場合は、同じ親を持つノードがリンクされたリストを構成する B ツリーです。リンクされたリスト内の各「前の」ポインターが同じ親を持つ別のノードを指すように強制しようとしています。親が null の場合は、親も null である別のノードを指す必要があります。

4

1 に答える 1

1

これを試して:

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. */
于 2010-10-13T18:27:22.547 に答える