CONNECT_BY_ISCYCLE в Oracle SQL: как найти циклы в иерархии

🟢 CONNECT_BY_ISCYCLE в Oracle SQL. Введение

Oracle SQL предоставляет удобную возможность строить иерархические запросы с помощью CONNECT BY. Но что, если в данных присутствует цикл — то есть запись ссылается на саму себя (напрямую или через потомков)? Это может вызвать бесконечную рекурсию и ошибки. Чтобы этого избежать, Oracle ввёл CONNECT_BY_ISCYCLE, который определяет, была ли строка частью цикла.


🔤 Написание

sql
SELECT столбцы, CONNECT_BY_ISCYCLE
FROM таблица
START WITH ...
CONNECT BY NOCYCLE PRIOR ...;

🔹 CONNECT_BY_ISCYCLE возвращает:

  • 1, если строка была частью цикла

  • 0, если нет


🔄 Где часто используется

  • Проверка целостности иерархии

  • Поиск ошибок в ссылках

  • Защита от бесконечных рекурсий

  • Аудит данных и дерева зависимостей

  • В графовых структурах и задачах


🧪 10 Примеров использования CONNECT_BY_ISCYCLE с пояснениями

1️⃣ Простой запрос с NOCYCLE и CONNECT_BY_ISCYCLE

sql
SELECT employee_id, manager_id, CONNECT_BY_ISCYCLE
FROM employees
START WITH manager_id IS NULL
CONNECT BY NOCYCLE PRIOR employee_id = manager_id;

Определяем, есть ли циклы в структуре подчинённости.


2️⃣ Фильтрация только циклических строк

sql
SELECT *
FROM employees
WHERE CONNECT_BY_ISCYCLE = 1
START WITH manager_id IS NULL
CONNECT BY NOCYCLE PRIOR employee_id = manager_id;

Ищем именно те строки, которые зациклены.


3️⃣ Иерархия с пометками «Цикл»/»ОК»

sql
SELECT employee_id,
CASE CONNECT_BY_ISCYCLE
WHEN 1 THEN 'Цикл'
ELSE 'ОК'
END AS статус
FROM employees
START WITH manager_id IS NULL
CONNECT BY NOCYCLE PRIOR employee_id = manager_id;

Выводим статус строки.


4️⃣ Комбинация с LEVEL

sql
SELECT LEVEL, employee_id, CONNECT_BY_ISCYCLE
FROM employees
START WITH manager_id IS NULL
CONNECT BY NOCYCLE PRIOR employee_id = manager_id;

Уровень + информация о цикле.


5️⃣ Путь с циклом (симуляция)

sql
SELECT SYS_CONNECT_BY_PATH(employee_id, ' → ') AS path,
CONNECT_BY_ISCYCLE
FROM employees
START WITH manager_id IS NULL
CONNECT BY NOCYCLE PRIOR employee_id = manager_id;

Показать путь и указать, где цикл.


6️⃣ Обнаружение циклов в категорийной структуре

sql
SELECT category_id, parent_id, CONNECT_BY_ISCYCLE
FROM categories
START WITH parent_id IS NULL
CONNECT BY NOCYCLE PRIOR category_id = parent_id;

Проверка структуры категорий.


7️⃣ Объединение с CONNECT_BY_ISLEAF

sql
SELECT employee_id, CONNECT_BY_ISLEAF, CONNECT_BY_ISCYCLE
FROM employees
START WITH manager_id IS NULL
CONNECT BY NOCYCLE PRIOR employee_id = manager_id;

Показываем: лист, или цикл.


8️⃣ Удаление или логирование циклов

sql
INSERT INTO audit_cycles (id)
SELECT employee_id
FROM employees
WHERE CONNECT_BY_ISCYCLE = 1
START WITH manager_id IS NULL
CONNECT BY NOCYCLE PRIOR employee_id = manager_id;

Сохраняем подозрительные записи в отдельную таблицу.


9️⃣ Визуализация дерева с отметками

sql
SELECT LPAD(' ', LEVEL * 2) || employee_id AS tree_view,
CONNECT_BY_ISCYCLE
FROM employees
START WITH manager_id IS NULL
CONNECT BY NOCYCLE PRIOR employee_id = manager_id;

Структура дерева с пометкой цикла.


🔟 Отчёт по числу циклов

sql
SELECT COUNT(*) AS cycle_count
FROM employees
WHERE CONNECT_BY_ISCYCLE = 1
START WITH manager_id IS NULL
CONNECT BY NOCYCLE PRIOR employee_id = manager_id;

Сколько строк участвуют в циклах.


🧩 CONNECT_BY_ISCYCLE в Oracle SQL. Заключение

CONNECT_BY_ISCYCLE — незаменимый помощник при поиске и устранении ошибок в иерархических данных. В связке с NOCYCLE он предотвращает зацикливание запросов и позволяет безопасно обходить деревья.

💡 Полезно:

  • Обязательно использовать NOCYCLE, иначе CONNECT_BY_ISCYCLE не работает

  • Результат — 1 для циклов, 0 для обычных строк

  • Идеален для диагностики данных


🔜 Следующая статья:

SAMPLE BLOCK в Oracle SQL — как выбрать случайные блоки данных


Понравилась статья? Поделиться с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии