Рекурсивные вызовы базы данных в Perl - PullRequest
4 голосов
/ 25 июня 2010

Я знаю, что есть простой способ сделать это, но мои рекурсивные способности вне практики.Учитывая таблицу базы данных, которая имеет три поля:

id
label
child_id

Я должен быть в состоянии собрать рекурсивную функцию, которая выдаст такой результат:

child (input of program)
  parent1
  parent2
    grandparent1
      great-grandparent1
    grandparent2
    grandparent3
  parent3
    grandparent4
    grandparent5

Я знаю, это должно быть легко, но я не могу заставить свой разум пройти умственную гимнастику, чтобы заставить это работать.Кроме того, это хорошая вещь, чтобы сделать?Похоже, что я мог бы в конечном итоге оставить открытым несколько соединений с базой данных.

Я думаю, что это та часть, которая затрудняет мне.Я начинаю с child_id и продолжаю свой путь.И у ребенка может быть много родителей.Таким образом, выводом будет дочерний идентификатор в «корне» дерева, а затем его родители, бабушки и дедушки для каждой ветви.Чем больше я думаю об этом, тем больше это традиционная формула «один родитель, много бабушек и дедушек», за исключением семантики.Я мог бы просто подумать об этом.

Стол будет выглядеть примерно так:

table parents

id    child_id    label
 1     NULL       child
 2     1          parent1
 3     1          parent2
 4     1          parent3
 5     3          grandparent1
 6     3          grandparent2
 7     3          grandparent3
 8     5          great-grandparent1
 9     4          grandparent4
10     4          grandparent5

Ответы [ 2 ]

3 голосов
/ 25 июня 2010

Вы можете попробовать вот так

sub getChildren {
  my $id = shift;
  my $depth = shift;
  my $sql = qq/SELECT id,label,child_id FROM table WHERE id=?/;
  my $sth = $db->prepare($sql);
  my $sth->execute($id);
  while(my ($id,$label,$child_id)=$sth->fetchrow_array) {
    print " "x$depth,$label;
    getChildren($child_id,$depth++);
 }
}
getChildren($id);
0 голосов
/ 27 июня 2010

Я действительно объяснил довольно похожую проблему в своем блоге, Реализация поиска в глубину в хранимой процедуре PostgreSQL , и мой способ решения этой проблемы с использованием perl.

Если ваша база данных не поддерживает хранимые процедуры, вы можете сделать то же самое на стороне клиента, но сначала вам нужно извлечь всю таблицу и сделать это в памяти.

Конечно, вы можете делать это рекурсивно и извлекать каждую запись по мере продвижения, но она не будет масштабироваться из-за накладных расходов оператора SQL (за исключением, может быть, SQLite). Если производительность не является проблемой, это, безусловно, самое простое решение.

...