5

我正在尝试执行以下脚本:

#!/usr/bin/perl -w

use strict;
use DBI;

my $db = "Pg";
my $db_database = "whatever";
my $user = "whatever";
my $password = "whatever";

my $dbh = DBI->connect("dbi:$db:dbname=$db_database", $user, $password);

my $query = $dbh->prepare (q{SELECT
                   arrival_date - INTERVAL '? MINUTE'
                   FROM emails LIMIT 1})
  or die ("unable to prepare");
$query->execute(60) or die("unable to execute");

print $query->fetchrow_array, "\n";

(arrival_date 有这种格式:time zone NOT NULL default CURRENT_TIMESTAMP 的时间戳)

问题是未检测到问号占位符,因为它在单引号内:

DBD::Pg::st execute failed: called with 1 bind variables when 0 are needed 

如果我使用 qq{}、$1 占位符并尝试使用 $dbh->quote 的一些变体,这将无济于事。我怎样才能使这项工作?

4

3 回答 3

10

您不能在引号内使用占位符。您可以使用 SQL 字符串连接,但在这种情况下,使用乘法更容易做到这一点:

my $query = $dbh->prepare (q{SELECT
                   arrival_date - ? * INTERVAL '1 MINUTE'
                   FROM emails LIMIT 1});
$query->execute(60);

这样,您不必' minutes'在执行查询时附加到数字。

于 2012-05-18T21:33:07.523 回答
3

我刚刚在这里找到了一个解决方案:http: //bugs.debian.org/cgi-bin/bugreport.cgi?bug= 321917

它使用 ?::interval 而不是 'interval ?' 工作:

my $query = $dbh->prepare (q{SELECT
                   arrival_date - ?::interval
                   FROM emails LIMIT 1});

$query->execute('60 MINUTE');
于 2012-05-18T21:29:30.600 回答
2
my $query = $dbh->prepare (<<SQL) or die ("unable to prepare");
SELECT arrival_date - INTERVAL ? FROM emails LIMIT 1
SQL
$query->execute("60 MINUTE");

或者

my $query = $dbh->prepare (<<SQL) or die ("unable to prepare");
SELECT arrival_date - INTERVAL CONCAT(?, " MINUTE") FROM emails LIMIT 1
SQL
$query->execute(60);

于 2012-05-18T21:14:52.797 回答