組織内に支店用のテーブルがあるとします。それらのいくつかは「メイン」ブランチであり、その他はメイン ブランチにロールアップされるサテライト オフィスです。システム内のいくつかの事柄にのみ影響するこの違いを除けば、ブランチはすべてピアであり、同じ属性 (アドレスなど) を持っています。これをモデル化する 1 つの方法は、次のような表です。
CREATE TABLE Branch (
branch_id INT NOT NULL PRIMARY KEY IDENTITY(1,1),
branch_name VARCHAR(80) NOT NULL,
street VARCHAR(80) NULL,
city VARCHAR(30) NULL,
state CHAR(2) NULL,
zip CHAR(5) NULL,
is_satellite_office BIT NOT NULL DEFAULT(0),
satellite_to_branch_id INT NULL REFERENCES Branch(branch_id)
)
Where is_satellite_office
= 1 このレコードが別のブランチsatellite_to_branch_id
のサテライトであり、サテライトであるブランチがある場合はそのブランチを参照します。
これらの 2 つの列が特定のレコードで一致するように、テーブルに制約を設定するのは簡単です。
CONSTRAINT [CK_Branch] CHECK
(
(is_satellite_office = 0 AND satellite_to_branch_id IS NULL)
OR (is_satellite_office = 1 AND satellite_to_branch_id IS NOT NULL)
)
しかし、私が本当に欲しいのは、この再帰が1レベルの深さだけになることを保証する方法です...つまり、親としてブランチを指す場合、それは親自体を持ってはならず、その値is_satellite_office
は0. 別の言い方をすれば、私は完全に再帰的なツリー構造を望んでいません。単一の親子関係に制限したいだけです。それが私がコードを書く方法であり、完全にがらくたのように実行されないデータベースでそれを強制する方法があれば、私はそうしたいと思います。
何か案は?私は MSSQL 2005 に取り組んでいますが、一般的な (ベンダー固有ではない) ソリューションが優先されます。他に方法がない場合を除き、トリガーを適用する必要はありません。
編集: 明確にするためsatellite_to_branch_id
に、同じブランチ テーブル内の別のレコードへの再帰的なポインターです。is_satellite_office BIT
を削除して、同じ情報を提供することに頼ることができることは知っていIsNull(satellite_to_branch_id)
ますが、明示的にする方が少し明確であり、さらに、それは質問の要点ではありません。再帰の深さが 1 を超えるのを防ぐための純粋な SQL 制約の方法を本当に探しています。