5

我们的网站使用 Perl 为我们的人力资源人员提供一个简单的机制来将职位空缺发布到我们的网站。它是由第三方开发的,但他们早就开始接触了,遗憾的是我们内部没有任何 Perl 技能。当营销人员绕过他们的内部 IT 团队时,就会发生这种情况!

我需要对此应用程序进行简单的更改。目前,职位空缺页面显示“我们目前有以下职位空缺:”,无论是否有职位空缺!所以我们想改变它,使这条线只在适当的时候显示。

显然,我可以开始学习一点 Perl,但我们已经在计划一个替代站点,而且它肯定不会使用 Perl。因此,由于解决方案对于具有这些技能的人来说是微不足道的,我想我会寻求一些有针对性的帮助。

以下是列出职位空缺的程序的开始。

sub list {
  require HTTP::Date;
  import HTTP::Date;

  my $date = [split /\s+/, HTTP::Date::time2iso(time())]->[0];

  my $dbh = DBI->connect($dsn, $user, $password)
    || die "cannot connect to $database: $!\n";

  my $sql = <<EOSQL;
SELECT * FROM $table where expiry >= '$date' order by expiry
EOSQL

  my $sth = $dbh->prepare($sql);
  $sth->execute();


  while (my $ref = $sth->fetchrow_hashref()) {
    my $temp  = $template;
    $temp     =~ s#__TITLE__#$ref->{'title'}#;

    my $job_spec = $ref->{'job_spec'};

...etc...

关键线是while (my $ref = $sth->fetchrow_hashref()) {。我想这是在说'虽然我可以从返回的记录集中拉出另一个空缺......'。如果我将打印语句放在这一行之前,它将始终显示;在这条线之后,每个空缺都会重复。

我如何确定有一些空缺要显示,而不会过早地通过返回的记录集?

我总是可以在 while 循环中复制代码,并将其放在 if() 语句中(在 while 循环之前),该语句也将包括我的 print 语句。但我更喜欢使用更简单的方法If any records then print "We currently have.." line。不幸的是,即使是这条简单的代码,我也不知道如何编写代码。

看,我告诉过你这是一个微不足道的问题,即使考虑到我笨拙的解释!

TIA

克里斯

4

9 回答 9

15

一个非常简单的方法是:

$sth->execute();

my $first = 1;
while (my $ref = $sth->fetchrow_hashref()) {
    if( $first ) {
        print "We currently have the following vacancies:\n";
        $first = 0;
    }
    my $temp  = $template;
    ...
}
if( $first ) {
    print "No vacancies found\n";
}
于 2008-11-14T13:55:39.997 回答
3

这与其说是一个 Perl 问题,不如说是一个数据库问题,并且在获得结果之前没有什么好方法可以知道您有多少结果。你在这里有两个选择:

  1. 执行执行“选择计数(*)”的查询以查看有多少行,然后执行另一个查询以获取实际行或
  2. 执行查询并将结果存储到散列中,然后计算散列中有多少条目,然后遍历散列并打印出结果。

例如,在我的脑海中:

my @results = ();
while (my $ref = $sth->fetchrow_hashref()) {
   push @results, $ref;
}

if ($#results == 0) {
  ... no results
} else {
  foreach $ref (@results) {
    my $temp = $template;
    ....
 }
于 2008-11-14T13:55:11.493 回答
3

如果您使用的是 Mysql,“rows”方法可以正常工作:

$sth->execute();

if($sth->rows) {
  print "We have data!\n";
}

while(my $ref = $sth->fetchrow_hashref()) {
...
}

该方法和一些注意事项在“perldoc DBI”中详细记录。始终以“perldoc”开头。

于 2008-11-14T16:51:26.537 回答
2

由于每个人都想优化在 Graeme 的解决方案中是否已打印标题的重复测试,因此我在其上提出了这个小变化:

$sth->execute();

my $ref = $sth->fetchrow_hashref();
if ($ref) {
  print "We currently have the following vacancies:\n";
  while ($ref) {
    my $temp  = $template;
    ...
    $ref = $sth->fetchrow_hashref();
  }
} else {
    print "No vacancies found\n";
}
于 2008-11-14T19:17:34.650 回答
2

由于您的查询是SELECT,因此您不能利用行或执行本身返回的值。

但是,您可以通过添加另一个查询来预先计算您的查询将选择多少行(即空缺)......像这样:

# Retrieve how many vacancies are currently offered:
my $query = "SELECT COUNT(*) AS rows FROM $table WHERE expiry >= ?";
$sth = $dbh->prepare($query);
$sth->execute($date);
$numVacancies = $numinfo->fetchrow_arrayref()->[0];

# Debug:
print "Number of vacancies: " . $numVacancies . "\n";

if ( $numVacancies == 0 ) { # no vacancy found...
    print "No vacancies found!\n";
}
else { # at least a vacancy has been found...
    print "We currently have the following vacancies:\n";

    # Retrieve the vacancies:
    my $sql = "SELECT * FROM $table where expiry >= '$date' ORDER BY expiry";
    my $sth = $dbh->prepare($sql);
    $sth->execute();

    ...
}

或者,类似地,您可以使用selectrow_array在一次调用中完成所有操作,而不是“准备”“执行”查询然后使用“fetchrow_array”

# Retrieve how many vacancies are currently offered:
my $query = "SELECT COUNT(*) AS rows FROM $table WHERE expiry >= ?"; 
my $numVacancies = $dbh->selectrow_array($query, undef, $date);

# Debug:
print "Number of vacancies: " . $numVacancies . "\n";

selectall_arrayref也是如此:

# Retrieve how many vacancies are currently offered:
my $query = "SELECT COUNT(*) AS rows FROM $table WHERE expiry >= ?";
my $numVacancies = $dbh->selectall_arrayref($query, {Slice => {}}, $date);

# Debug:
print "Number of vacancies: " . @$numVacancies[0]->{rows} . "\n";

但是,如果您使用selectrow_arrayselectall_arrayref,您也可以直接从原始查询的结果中检索空缺数量:

# Retrieve the vacancies:
my $sql = "SELECT * FROM $table where expiry >= ? ORDER BY expiry";
my $vacancies = $dbh->selectall_arrayref($sql, {Slice => {}}, $date);

# Debug:
print "Number of vacancies: " . scalar @{$vacancies} . "\n";
于 2014-10-16T14:59:53.333 回答
1

一种更有效的方法(避免循环内的条件),如果你不介意它改变页面的输出方式(一次而不是一次),你可以创建一个变量来保存在循环之前输出:

my $output = '';

然后在循环内,将任何打印语句更改为如下所示:

$output .= "whatever we would have printed";

然后在循环之后:

if ($output eq '')
{
  print 'We have no vacancies.';
}
else
{
  print "We currently have the following vacancies:\n" . $output;
}
于 2008-11-14T14:03:37.703 回答
1

只需添加另一个查询.. 像这样:

# count the vacancies    
$numinfo = $dbh->prepare("SELECT COUNT(*) FROM $table WHERE EXPIRY >= ?");
$numinfo->execute($date);
$count = $numinfo->fetchrow_arrayref()->[0];

# print a message
my $msg = '';
if   ($count == 0) $msg = 'We do not have any vacancies right now';
else               $msg = 'We have the following vacancies';
print($msg);
于 2008-11-14T14:05:06.250 回答
1
use Lingua::EN::Inflect 'PL';

$sth->execute();
my $results = $sth->fetchall_arrayref( {}, $max_rows );

if (@$results) {
    print "We currently have the following ", PL("vacancy",scalar @$results), ":\n";

    for my $ref (@$results) {
        ...
    }
}
于 2008-11-14T18:06:40.410 回答
-2

perldoc DBI 说:

 For a non-"SELECT" statement, "execute" returns the number of rows
 affected, if known. If no rows were affected, then "execute"
 returns "0E0", which Perl will treat as 0 but will regard as true.

所以答案是检查$sth->execute()的返回值:

 my $returnval = $sth->execute;
 if (defined $returnval && $returnval == 0) {
     carp "Query executed successfully but returned nothing";
     return;
 }
于 2008-11-15T04:28:45.880 回答