在Perl / Mysql中显示内容及其相关内容

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Perl / Mysql中显示内容及其相关内容相关的知识,希望对你有一定的参考价值。

我试图从像这样的小型Perl项目中获得此示例输出

   content1
        relatedcontent1
        relatedcontent2
        relatedcontent2
   content2
        relatedcontent1
        relatedcontent2 

这是我的代码

   #!C:/Perl64/bin/perl.exe
   use strict;
   use warnings;
   use v5.10; # for say() function
   use DBI;
   use html::Table;

   # mysql database configurations
   my $dsn = "DBI:mysql:naxum";
   my $username = "root";
   my $password = '';
   print "Content-Type:text/html

";
   # connect to MySQL database
   my %attr = ( PrintError=>0,  # turn off error reporting via warn()
         RaiseError=>1   # report error via die()
       );
   my $dbh = DBI->connect($dsn,$username,$password,\%attr);

   # query data from the sponsor table
   query_sponsor($dbh);
   query_person_by_target($dbh);

   sub query_sponsor{
   # query from the  table
    my ($dbh) = @_;
    my $sql = "SELECT name,id FROM sponsor";
    my $sth = $dbh->prepare($sql);
    # execute the query
   $sth->execute();
   print "<table>
";
   print "<thead>
";
   print "<tr>
";
   print "<th>Id</th>
";
   print "<th>Name</th>
";
   print "</tr>
";
   print "</thead>
";
   print "<tbody>
";
   while(my @row = $sth->fetchrow_array()){

 print "<tr>
";
 print "<td>
";
 print $row['1'];

  sub query_person_by_target{
      my ($dbhPerson) = @_;
      my $sqlPerson = "SELECT username, firstname FROM person WHERE sponsor_id = ?";
      my $sthPerson = $dbhPerson->prepare($sqlPerson);
     $sthPerson->execute($row['1']) or die "execution failed: $dbhPerson->errstr()";
      while ( my @rowPerson = $sthPerson->fetchrow_array()){
          print "<p>$rowPerson['0']</p>
";
      }
      $sth->finish();
 }
 print "</td>
";
 print "<td>$row['0']</td>
";
 print "</tr>
";
 }
 $sth->finish();
 print "</tbody>
";
 print "</table>
";
 }
 $dbh->disconnect();

但是,我无法得到我想要实现的输出。这是结果

   content1
   content2
   content3
   .....
   relatedcontent1

它只会在内容之外打印一个相关内容。每个内容和每个内容至少有3个相关内容。

答案

您可以在程序中的其他代码中间定义子例程。这让我觉得你希望它们在定义时执行,但事实并非如此 - 它们在你调用它们时执行。你打电话给他们是这样的:

query_sponsor($dbh);
query_person_by_target($dbh);

所以你得到query_sponsor()的所有输出以及query_person_by_name()的所有输出就不足为奇了。

一个更好的方法是从query_person_by_target()中调用query_sponsor()。我还将其分为两个阶段 - 第一阶段将数据提取到数据结构,第二阶段显示数据。

由于我没有您的数据库,因此此代码未经测试。

#!/usr/bin/perl

use strict;
use warnings;
use feature 'state'; # for state variables
use feature 'say';
use CGI 'header';

sub get_dbh {
  # MySQL database configurations
  my $dsn = "DBI:mysql:naxum";
  my $username = "root";
  my $password = '';
  # connect to MySQL database
  my %attr = (
    PrintError=>0,  # turn off error reporting via warn()
    RaiseError=>1,  # report error via die()
  );

  return DBI->connect($dsn, $username, $password, \%attr);
}

sub query_sponsor {
  state $dbh = get_dbh();

  my $sql = 'select name, id from sponsor';
  my $sth = $dbh->prepare($sql);
  $sth->execute;

  my @sponsors;

  while (my @row = $dbh->fetchrow_array) {
    push @sponsors, {
      name   => $row[0],
      id     => $row[1],
      people => get_people_for_sponsor($row[1]),
    };
  }

  return @sponsors;
}

sub get_people_for_sponsor {
  my ($sponsor_id) = @_;

  state $dbh = get_dbh;

  my $sql = 'select username, firstname
             from   person
             where  sponsor_id = ?';
  my $sth = $dbh->prepare;
  $sth->execute($sponsor_id);
  my @people;
  while (my @row = $sth->fetchrow_array) {
    push @people, {
      username  => $row[0],
      firstname => $row[1],
    };
  }

  return @people;
}

my @sponsors = query_sponsor();

# Now you have all of your data in @sponsors. You simply need
# to walk that array and use the data to build the output you
# want. My example is plain text - it shouldn't be too hard to
# convert it to HTML.

print header('text/plain');

for my $s (@sponsors) {
  say "$s->{id}: $s->{name}";
  for my $p (@{$s->{people}}) {
    say "* $p->{firstname} / $p->{username}";
  }
}

我还建议您使用类似Template Toolkit的东西来生成输出。将原始HTML放入Perl程序是一个可怕的想法 - 它可以保证变成一个难以维护的混乱:-)

另一答案

是的,根据你所说的声明是正确的。

你已经声明了两个子程序,并且你一个接一个地调用它,所以它正在执行,例如考虑下面的一个

sub1();
sub2();

sub sub1()
{
    for(0..5)
    {
        print "hello
";
        sub sub2()
        {
            print "hi
";

        }
    }
}

#output
hello
hello
hello
hello
hello
hello
hi

所以你应该删除子query_person_by_target子程序或调用父子程序query_sponsor中的子子程序,并在sub和loop之外声明子子程序,如下所示(未测试)

query_sponsor($dbh);

sub query_sponsor
{
    # query from the  table
    my ($dbh) = @_;
    my $sql = "SELECT name,id FROM sponsor";
    my $sth = $dbh->prepare($sql);
    # execute the query
    $sth->execute();
    print "<table>
";
    print "<thead>
";
    print "<tr>
";
    print "<th>Id</th>
";
    print "<th>Name</th>
";
    print "</tr>
";
    print "</thead>
";
    print "<tbody>
";
    while(my @row = $sth->fetchrow_array())
    {

        print "<tr>
";
        print "<td>
";
        print $row['1'];

        query_person_by_target($dbh);

        print "</td>
";
        print "<td>$row['0']</td>
";
        print "</tr>
";
    }
    $sth->finish();
    print "</tbody>
";
    print "</table>
";
}

sub query_person_by_target{
    my ($dbhPerson) = @_;
    my $sqlPerson = "SELECT username, firstname FROM person WHERE sponsor_id = ?";
    my $sthPerson = $dbhPerson->prepare($sqlPerson);
    $sthPerson->execute($row['1']) or die "execution failed: $dbhPerson->errstr()";
    while ( my @rowPerson = $sthPerson->fetchrow_array()){
        print "<p>$rowPerson['0']</p>
";
    }
    $sth->finish();
}
$dbh->disconnect();

以上是关于在Perl / Mysql中显示内容及其相关内容的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 cgi python 脚本在浏览器中显示 pdf 文件内容及其全名?

如何将来自三个 Perl 数组的数据插入到单个 MySQL 表中?

如何在 MySQL 中表示树及其内容?

使用 JavaScript 和 Perl 处理表单内容

UIWindow 及其内容未在 Xcode 11 iOS 13 中显示。出现黑屏

扫描目录并显示子目录及其内容