Let's say you have a table for branches in your organization. Some of them are "main" branches, and others are satellite offices that roll up to a main branch. Other than this distinction, which only impacts a few things in the system, the branches are all peers and have the same attributes (address, etc.). One way to model this is in a table like:
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 iff this record is a satellite to another branch, and satellite_to_branch_id
refers to which branch you're a satellite of, if any.
It's easy enough to put a constraint on the table so that those two columns agree on any given record:
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)
)
However, what I really want is a way to guarantee that this recursion only goes one level deep ... that is, that if I point to a branch as my parent, it must not have a parent itself, and its value for is_satellite_office
must be 0. Put differently, I don't really want a fully recursive tree structure, I just want to limit it to a single parent / child relationship. That's how I'm going to write the code, and if there's a way to enforce it in the database that won't perform like total crap, I'd like to.
Any ideas? I'm working on MSSQL 2005, but general (non-vendor-specific) solutions are preferred. And no triggers need apply, unless there's truly no other way to do it.
EDIT: To be clear, satellite_to_branch_id
is the recursive pointer to another record in the same Branch table. I know that I could remove the is_satellite_office BIT
and rely on IsNull(satellite_to_branch_id)
to give me the same information, but I find it's a little clearer to be explicit, and besides which, that's not the gist of the question. I'm really looking for a pure SQL-constraint way to prevent recursion-depth of greater than 1.