Делфи Бележки Работа с n-ary дървета в PL

Забележки на програмиста Delphi + Oracle

Работа с n-арни дървета в PL/SQL

Представете си почти класическа ситуация: в базата данни има някои данни (една, две или повече таблици) и трябва да обработите тези данни по умен начин и след това да запишете резултата в отделна таблица за по-късно представяне на данните в потребителя.

Законът не е забранен да избира данни за клиентско приложение, да ги обработва локално и след това да записва резултата обратно в базата данни, но е изключително неразумно. Освен това, колкото по-голямо е количеството на първоначалните данни, толкова повече време отнема простото вземане на данни. Следователно всякакви задачи, свързани с обработката на данни, се решават най-добре от страна на сървъра.

Да кажем, че в процеса на обработка на данни трябва да изградим дърво.

В Delphi структурата на дървесния възел може да бъде описана по следния начин:

Процедурата за създаване на дървесен възел в този случай може да бъде следната:

Е, процедурата за итерация за всички дъщерни възли:

Мисля, че даденият код е достатъчен, за да разберем за какво става дума.

Сега нека се опитаме да направим нещо подобно от страна на сървъра.

Интерпретираният език на PL/SQL на Oracle е много мощен в правилните ръце. Той обаче има някои неприятни ограничения. Например в PL/SQL няма указатели и следователно не можете да се позовавате на типове данни, които все още не са декларирани (или декларирани в кода по-долу). Следователно, ако пишете така:

тогава ще получим грешка при компилация. И не е ясно как да се препраща към родителския възел.?

Изправен пред такъв проблем, аз наистина исках да разреша проблема с помощта на обекти. Но обектът в Oracle е тип SQL и логиката за обработка на данни трябва да бъде внедрена в PL/SQL и следователно има някои неприятни моменти. Например не всички типове данни PL/SQL могат да се използват в SQL. И работата с обекти е по-бавна, отколкото с PL/SQL масивите (колекции).

По този начин, PL/SQL структура на данни може да бъде описана по следния начин:

Тук трябва да обърнете внимание на:

  • g_nodes е колекция от възли, декларирани индекс от pls_integer, което означава, че g_nodes не трябва да се инициализира отделно.
  • g_nodes_seq е брояч на възли, съхранявани в g_nodes, като цяло можете да го направите и без него, но това е необходимо за удобство.
  • p_root_node - индексът, при който ще се съхранява коренът на дървото.

Сега, за да изградим дървото, се нуждаем от следните функции:

Мисля, че тук всичко е ясно: започваме да изграждаме дървото от корена (create_root), след това създаваме възли (create_node).

Итерацията на дървото се извършва по следния начин:

Е, като цяло, нещо подобно. Оказа се малко тромаво, но работи и работи достатъчно бързо.

Ако не се изисква навигация „нагоре“ от възела, тогава описанието на структурата на t_node може да бъде опростено.