Допустим, у вас есть таблица для филиалов в вашей организации. Некоторые из них являются «основными» филиалами, а другие - спутниковыми офисами, которые сворачиваются в основной филиал. Помимо этого различия, которое влияет только на несколько вещей в системе, все ветви являются одноранговыми и имеют одинаковые атрибуты (адрес и т. Д.). Один из способов смоделировать это в виде таблицы:
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)
)
Где is_satellite_office
= 1, если эта запись является спутником для другой ветви, а satellite_to_branch_id
указывает, к какой ветви вы относитесь, если таковая имеется.
Достаточно просто наложить ограничение на таблицу, чтобы эти два столбца согласовали любую запись:
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)
)
Однако то, что я действительно хочу, это способ гарантировать, что эта рекурсия пойдет только на один уровень глубины ... то есть, если я указываю на ветвь как своего родителя, она не должна сам родитель, и его значение для is_satellite_office
должно быть 0. Другими словами, я не хочу полностью рекурсивную древовидную структуру, я просто хочу ограничить ее одним родителем / дочерним отношением. Вот как я собираюсь написать код, и если есть способ применить его в базе данных, который не будет работать как полная чушь, я бы хотел.
Есть идеи? Я работаю над MSSQL 2005, но предпочтительны общие (не зависящие от поставщика) решения. И никакие триггеры не должны применяться, если действительно нет другого способа сделать это.
EDIT: для ясности, satellite_to_branch_id
- рекурсивный указатель на другую запись в той же таблице ветвления. Я знаю, что мог бы удалить is_satellite_office BIT
и полагаться на IsNull(satellite_to_branch_id)
, чтобы дать мне ту же информацию, но я нахожу, что это немного яснее, чтобы быть явным, и, кроме того, это не суть вопроса. Я действительно ищу чистый способ ограничения SQL, чтобы предотвратить глубину рекурсии больше 1.