Posting comment as answer, as requested.
Generate your own placeholder string. Like so:
my @nums = (22,23);
my $placeholder = join ",", ("?") x @nums;
$query->execute(@nums);
Вопрос
I know I can do this with interpolation. Can I do it using placeholders?
I am getting this error:
DBD::Pg::st execute failed: ERROR: invalid input syntax for integer: "{"22,23"}" at ./testPlaceHolders-SO.pl line 20.
For this script:
#!/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";
}
Is there a way around it besides interpolation?
Решение 2
Posting comment as answer, as requested.
Generate your own placeholder string. Like so:
my @nums = (22,23);
my $placeholder = join ",", ("?") x @nums;
$query->execute(@nums);
Другие советы
DBD::PG
has support for PostgreSQL arrays, so you can simply write a query like this:
WHERE typeid = ANY( ARRAY[1,2,3] )
or, with a parameter...
WHERE typeid = ANY(?)
Then just use the array support
my @targets = (1,2,3);
# ...
$query->execute(\@targets);
Yes. You must use placeholders for each value, such as IN (?, ?, ?)
. You can however generate the correct number of question marks using something like this (untested):
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);
Note that if you use an ORM such as DBIx::Class instead, this sort of ugly hack gets abstracted away.
You have to build the SQL statement with the correct number of question marks and then set the parameter values. There is no way to bind a list to a single question mark.