使用Perl DBI获取所有记录

cjd*_*3SD 4 perl dbi

我有一个使用DBI连接的Perl脚本.我使用子例程打开并读取SQL脚本文件.我只打印一条记录,我应该再打印两条记录(总共三条记录).我如何获得所有记录?

结果:

Alert:OUTBOUND_DATA:0
Run Code Online (Sandbox Code Playgroud)

脚本:

my $dbh_oracle = DBI->connect(
          $CFG{oracle_dbi_connect},
          $CFG{db_user},
          $CFG{db_cred},
          {AutoCommit => 0,
           RaiseError => 0,
           PrintError => 0}) or die ("Cannot connect to the database: ".$DBI::errstr."\n");

my ($val1, $val2) = get_data();
print "Alert:$val1:$val2\n";

send_email("Alert:$val1:$val2");

sub get_data
{
  undef $/;
  open (my $QFH, "< /sql/summary.sql") or die "error can't open this file $!";
  my $sth= $dbh_oracle->prepare(<$QFH>) or
      die ("Cannot connect to the database: ".$DBI::errstr."\n");
  $sth->execute;
  close $QFH;
  my $row = $sth->fetchrow_hashref;
  $sth->finish;
  return @$row{'MYTABLE','FLAG'};
}

sub send_email {
    my $message = shift;
    open (MAIL, "|/usr/sbin/sendmail -t") or die "Can't open sendmail: $!";
    print MAIL "To: me\@test.com\n";
    print MAIL "From: Data\n";
    print MAIL "\n";
    print MAIL $message;
    close MAIL;
}
exit;
Run Code Online (Sandbox Code Playgroud)

运行查询的结果:(超过1 rec)

MYTABLE                  FLAG
----------------------- ----------
OUTBOUND_DATA         0
MSGS_BY_DIM                  0
INBOUND_DATA         0

3 rows selected.
Run Code Online (Sandbox Code Playgroud)

Ωme*_*ega 8

有许多不同的方法可以从语句句柄中检索数据.最常见的是非常简单,它们的使用如下所示:

my @row_array = $sth->fetchrow_array;
my $array_ref = $sth->fetchrow_arrayref;
my $hash_ref  = $sth->fetchrow_hashref;
Run Code Online (Sandbox Code Playgroud)

第一个,fetchrow_array,将依次返回每一行作为数组.使用上面选择返回的数据的示例可以是:

while (my @row_array = $sth->fetchrow_array) {
    print $row_array[0], " is ", $row_array[1], " years old, and has a " , 
          $row_array[2], "\n";
}
Run Code Online (Sandbox Code Playgroud)

第二个示例类似但返回数组引用而不是数组:

while (my $array_ref = $sth->fetchrow_arrayref) {
    print $array_ref->[0], " is ", $array_ref->[1], 
          " years old, and has a " , $array_ref->[2], "\n";
}
Run Code Online (Sandbox Code Playgroud)

第三个例子fetchrow_hashref通常最具可读性:

while (my $hash_ref = $sth->fetchrow_hashref) {
    print $hash_ref->{name}, " is ", $hash_ref->{age}, 
          " years old, and has a " , $hash_ref->{pet}, "\n";
}
Run Code Online (Sandbox Code Playgroud)


gka*_*pas 3

它还取决于您如何构建整个脚本。您的get_data()调用仅允许返回一对值。我至少看到了几个选项:要么返回包含所有数据的散列(引用)并让其组装main,要么使用前面提到的循环结构并在子例程内构造消息正文,仅返回单个标量字符串。

要将所有数据作为哈希引用返回,子get_data例程可能如下所示(注意我使用的fetchall_hashreffetchrow_hashref

sub get_data
{
  undef $/;
  open (my $QFH, "< /sql/summary.sql") or die "error can't open this file $!";
  my $sth= $dbh_oracle->prepare(<$QFH>) or
      die ("Cannot connect to the database: ".$DBI::errstr."\n");
  $sth->execute;
  close $QFH;
  my $hash_ref = $sth->fetchall_hashref('MYTABLE');
  $sth->finish;
  return $hash_ref;
}
Run Code Online (Sandbox Code Playgroud)

您可以按main如下方式调用它并使用输出:

my $hash_ref = get_data();
my $message = "";
foreach my $table (sort keys %$hash_ref) {
    $message .= join(":", "Alert", $table, $$hash_ref{$table}{'FLAG'}) . "\n";
}
Run Code Online (Sandbox Code Playgroud)

这将导致$message包含:

Alert:INBOUND_DATA:0
Alert:MSGS_BY_DIM:0
Alert:OUTBOUND_DATA:0
Run Code Online (Sandbox Code Playgroud)

你可能想礼貌地:

$dbh_oracle->disconnect;
Run Code Online (Sandbox Code Playgroud)

在你退出之前。

这有一些问题,例如,您已将 SQL 隐藏在外部脚本中,但我诉诸于对键(MYTABLE,我假设它在您的查询中是唯一的)和值(FLAG)进行硬编码脚本,稍后当您想对此进行扩展时,这将受到限制。