如何使用带有“in(...)”子句的占位符?

时间:2013-12-17 22:52:21

标签: perl postgresql dbi

我知道我可以用插值来做到这一点。我可以使用占位符吗?

我收到此错误:

DBD::Pg::st execute failed: ERROR:  invalid input syntax for integer: "{"22,23"}" at ./testPlaceHolders-SO.pl line 20.

对于这个脚本:

#!/usr/bin/perl -w

use strict;
use DBI;

# Connect to database.

my $dbh = DBI->connect("dbi:Pg:dbname=somedb;host=localhost;port=5432", "somedb", "somedb");

my $typeStr = "22,23";
my @sqlParms = [ $typeStr ];
my $sqlStr = << "__SQL_END";
    SELECT id
    FROM states
    WHERE typeId in (?)
    ORDER BY id;
__SQL_END

my $query = $dbh->prepare($sqlStr);
$query->execute(@sqlParms);

my $id;
$query->bind_columns(\$id);

# Process rows

while ($query->fetch())
{
    print "Id: $id\n";
}

除了插值之外还有办法吗?

4 个答案:

答案 0 :(得分:5)

DBD::PG支持PostgreSQL arrays,因此您只需编写如下查询:

WHERE typeid = ANY( ARRAY[1,2,3] )

或者,带参数......

WHERE typeid = ANY(?)

然后只使用数组支持

my @targets = (1,2,3);
# ...
$query->execute(\@targets);

答案 1 :(得分:1)

是。您必须为每个值使用占位符,例如IN (?, ?, ?)。但是,您可以使用以下内容生成正确数量的问号(未经测试):

my @values = (22, 23, ...);
# will produce "?, ?, ..."
my $in = join ", ", ("?") x @values;
my $sqlStr = "SELECT id FROM states WHERE typeId in ($in) ORDER BY id;";
my $query = $dbh->prepare($sqlStr);
$query->execute(@values);

请注意,如果您使用诸如DBIx::Class之类的ORM,那么这种丑陋的黑客就会被抽象掉。

答案 2 :(得分:1)

根据要求将评论作为回答发布。

生成您自己的占位符字符串。像这样:

my @nums = (22,23); 
my $placeholder = join ",", ("?") x @nums; 
$query->execute(@nums); 

答案 3 :(得分:0)

您必须使用正确数量的问号构建SQL语句,然后设置参数值。无法将列表绑定到单个问号。