Perl中递归调用数据库

发布于 2024-09-07 14:10:23 字数 902 浏览 6 评论 0原文

我知道有一种简单的方法可以做到这一点,但我的递归能力还不够实践。给定一个包含三个字段的数据库表:

id
label
child_id

我应该能够组合一个递归函数,给出如下输出:

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

我知道这应该很容易,但我无法让我的思想通过心理体操来实现它工作。另外,这是一件好事吗?看来我最终可能会打开相当多的数据库连接。

我认为这是让我感到困难的部分。我从一个 child_id 开始,然后逐步向上。而且一个孩子可以有很多个父母。因此,输出将是树“根”处的子 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

I know there's an easy way of doing this, but my recursion abilities are out of practice. Given a database table that has three fields:

id
label
child_id

I should be able to put together a recursive function that will give output like this:

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

I know it should be easy, but I can't get my mind to go through the mental gymnastics to make it work. Also, is this a good thing to do? Seems like I might end up leaving open quite a few database connections.

I think this is the part making it difficult for me. I'm starting with a child_id, and working my way up. And a child can have many parents. So, the output would be the child id at the 'root' of the tree and then it's parents and grandparents for each branch. The more I think about it, it's just the traditional 'one parent, many grandparents' formula, except for semantics. I could just be over thinking it.

The table would look something like this:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜吻♂芭芘 2024-09-14 14:10:23

你可以尝试这个方法

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);

You could try this way

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);
倒数 2024-09-14 14:10:23

我实际上在我的博客中解释了一个非常相似的问题, 实现深度首先在 PostgreSQL 存储过程中进行搜索,以及我使用 perl 解决此问题的方法。

如果您的数据库不支持存储过程,您可以在客户端执行相同的操作,但您需要首先获取整个表并在内存中执行此操作。

当然,您可以递归地执行此操作并在执行过程中获取每个条目,但由于 SQL 语句开销,它不会扩展(可能在 SQLite 上除外)。如果性能不是问题,这一定是迄今为止最简单的解决方案。

I actually explained a quite similar problem in my blog, Implementing a depth first search in a PostgreSQL stored procedure, and my way of solving this using perl.

If your database doesn't support stored procedures you can do the same thing client-side, but you need to fetch the entire table first and do it in memory.

You could of course do it recursively and fetch each entry as you go along, but it will not scale because of the SQL statement overhead (except maybe on SQLite). If performance is not a problem this must be by far the easiest solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文