我们的网站使用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()) {
。我想这是在说“我可以从退回的记录集中取出另一个空位......”。如果我在此行之前放置我的print语句,它将始终显示;在这一行之后,每个空缺都会重复。
如何确定是否有一些空位要显示,而不会过早地移动返回的记录集?
我总是可以在while循环中复制代码,并将它放在if()循环中的if()语句中,该语句也包含我的print语句。但我更愿意采用更简单的If any records then print "We currently have.." line
方法。不幸的是,即使是这条简单的行,我也没有线索。
看,我告诉过你,这是一个微不足道的问题,即使考虑到我的错误解释!
TIA
克里斯
答案 0 :(得分: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";
}
答案 1 :(得分:3)
这不是一个Perl问题,因为它是一个数据库问题,并且没有好的方法可以知道你拥有它们之前有多少结果。你有两个选择:
例如,脱离我的头顶:
my @results = ();
while (my $ref = $sth->fetchrow_hashref()) {
push @results, $ref;
}
if ($#results == 0) {
... no results
} else {
foreach $ref (@results) {
my $temp = $template;
....
}
答案 2 :(得分:3)
如果你使用的是Mysql,那么“rows”方法就可以了:
$sth->execute();
if($sth->rows) {
print "We have data!\n";
}
while(my $ref = $sth->fetchrow_hashref()) {
...
}
该方法和一些注意事项在“perldoc DBI”中有详细记录。始终以“perldoc”开头。
答案 3 :(得分: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";
}
答案 4 :(得分:2)
由于您的查询是 SELECT ,因此您无法利用rows或execute本身返回的值。
但是,您可以通过添加另一个查询来预先计算您的查询将选择多少行(即空位)......如下所示:
# 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();
...
}
或者,类似地,而不是&#34;准备&#34; 和&#34;执行&#34; 查询,然后使用&# 34; fetchrow_array&#34; ,您可以使用selectrow_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_array 或 selectall_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";
答案 5 :(得分:1)
更有效的方法(避免循环中的条件),如果你不介意它改变页面输出的方式(一次一个而不是一次一行)你可以做一个变量在循环之前保持输出:
my $output = '';
然后在循环内部,将任何print语句更改为:
$output .= "whatever we would have printed";
然后循环:
if ($output eq '')
{
print 'We have no vacancies.';
}
else
{
print "We currently have the following vacancies:\n" . $output;
}
答案 6 :(得分: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);
答案 7 :(得分: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) {
...
}
}
答案 8 :(得分:-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-&gt; execute()的返回值:
my $returnval = $sth->execute;
if (defined $returnval && $returnval == 0) {
carp "Query executed successfully but returned nothing";
return;
}