Вопрос

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top