Gert van den Berg
Gert van den Berg

Reputation: 2785

Perl DBI - binding a list

How do I bind a variable to a SQL set for an IN query in Perl DBI?

Example:

my @nature = ('TYPE1','TYPE2'); # This is normally populated from elsewhere
my $qh = $dbh->prepare(
      "SELECT count(ref_no) FROM fm_fault WHERE nature IN ?"
) || die("Failed to prepare query: $DBI::errstr");

# Using the array here only takes the first entry in this example, using a array ref gives no result
# bind_param and named bind variables gives similar results
$qh->execute(@nature) || die("Failed to execute query: $DBI::errstr");

print $qh->fetchrow_array();

The result for the code as above results in only the count for TYPE1, while the required output is the sum of the count for TYPE1 and TYPE2. Replacing the bind entry with a reference to @nature (\@nature), results in 0 results.

The main use-case for this is to allow a user to check multiple options using something like a checkbox group and it is to return all the results. A work-around is to construct a string to insert into the query - it works, however it needs a whole lot of filtering to avoid SQL injection issues and it is ugly...

In my case, the database is Oracle, ideally I want a generic solution that isn't affected by the database.

Upvotes: 3

Views: 3047

Answers (1)

mpapec
mpapec

Reputation: 50677

There should be as many ? placeholders as there is elements in @nature, ie. in (?,?,..)

my @nature = ('TYPE1','TYPE2');
my $pholders = join ",", ("?") x @nature;
my $qh = $dbh->prepare(
    "SELECT count(ref_no) FROM fm_fault WHERE nature IN ($pholders)"
) or die("Failed to prepare query: $DBI::errstr");

Upvotes: 4

Related Questions