Работа с самообращающимися таблицами / рекурсивными связями в SQL - это не просто. Я полагаю, это подтверждается тем фактом, что несколько человек не могут решить проблему, просто проверяя циклы одной глубины.
Чтобы применить это к табличным ограничениям, вам понадобится проверочное ограничение на основе рекурсивного запроса. В лучшем случае это специфичная для СУБД поддержка, и она может работать неэффективно, если ее нужно запускать при каждом обновлении.
Мой совет - использовать код, содержащий инструкцию UPDATE, для обеспечения этого. Это может принять несколько форм. В любом случае, если требуется строгое соблюдение, может потребоваться ограничение доступа UPDATE к таблице для учетной записи службы, используемой хранимым процедурой или внешней службой.
Использование хранимой процедуры может отличаться от ограничения CHECK, за исключением того, что вы можете использовать процедурную (итеративную) логику для поиска циклов перед выполнением обновления. Тем не менее, стало непопулярным помещать слишком много логики в хранимые процессы, и то, следует ли выполнять этот тип проверки, является оценочным призывом от команды к команде / организации / организации.
Аналогично, использование подхода, основанного на сервисе, позволит вам использовать процедурную логику для поиска циклов, и вы можете написать ее на языке, лучше подходящем для такой логики. Проблема здесь в том, что если сервисы не являются частью вашей архитектуры, то немного сложнее представить целый новый уровень. Но уровень обслуживания, вероятно, считается более современным / популярным (на данный момент, по крайней мере), чем передача обновлений через хранимые процессы.
С учетом этих подходов и понимания того, что как процедурный, так и рекурсивный синтаксис в базах данных зависит от СУБД, существует слишком много возможных вариантов синтаксиса, чтобы их можно было реально использовать. Но идея такова:
- Изучите предполагаемого родителя.
- Проверить его родительский рекурсивно
- Достигали ли вы когда-либо предполагаемого ребенка до того, как входили в аккаунт верхнего уровня? Если нет, разрешите обновление