Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to best enforce single-level recursion in a SQL table?
    primarykey
    data
    text
    <p>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:</p> <pre><code>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) ) </code></pre> <p>Where <code>is_satellite_office</code> = 1 iff this record is a satellite to another branch, and <code>satellite_to_branch_id</code> refers to which branch you're a satellite of, if any. </p> <p>It's easy enough to put a constraint on the table so that those two columns agree on any given record:</p> <pre><code>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) ) </code></pre> <p>However, what I really want is a way to guarantee that this recursion only goes <strong>one</strong> 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 <code>is_satellite_office</code> 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.</p> <p>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.</p> <p>EDIT: To be clear, <code>satellite_to_branch_id</code> is the recursive pointer to another record in the same Branch table. I know that I could remove the <code>is_satellite_office BIT</code> and rely on <code>IsNull(satellite_to_branch_id)</code> 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.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload