Reputation: 53
This is an addition to my solved question here: how to get array of zip codes within x miles in perl
OK, I have the array @zips. Now I am trying to use it in a query like this:
SELECT `club_name`,`city` FROM `table` WHERE `public_gig` = 'y' AND `zip` IN (@zips)
#I also tried syntax "IN ("@zips"), IN @zips and IN ('@zips')"
But, I cannot get it to work. (I am using placeholders and such as you see in my link above.)
I was able to get this to work:
$fzip=shift(@Zips);
$lzip=pop(@Zips);
SELECT `club_name`,`city` FROM `table` WHERE `public_gig` = 'y' AND `zip` BETWEEN $fzip AND $lzip
ZIP | public_gig | start_time | fin_time | city | club_name | and so on
33416 | y | 9pm | 2am | clearwater | beach bar | yada
But, for obvious reasons and some resemblance of accuracy, that is not really what I want. Just wanted to see if I could get SOMETHING working on my own.
Why can't I get the query to work with the zips in the array using IN?? Nothing is returned and there is no error.
There is actually a lot more in that query but, I left it all out to keep it short here.
I tried to figure it out by myself. Obviously, my learning capacity for the day is near peak.
Thanks for any help.
Upvotes: 5
Views: 8228
Reputation: 239980
All of the examples posted here will screw up if any of your values contain single-quotes, don't use them.
Instead (assuming $dbh
is the database handle for your mysql connection):
my $zip_string = join q{,}, map $dbh->quote($_), @zips;
and interpolate that.
Or, for something nice, but not half as outlandish as DBIx::Perlish: SQL::Abstract.
my $sqla = SQL::Abstract->new;
my ($sql, @bind) = $sqla->select(
'table',
['club_name', 'city'],
{
public_gig => y',
zip => { -in => \@zips },
}
);
$dbh->prepare($sql);
$dbh->execute(@bind);
# fetchrow etc.
Upvotes: 10
Reputation: 46187
This can be done using placeholders, you just have to work around the limitation that each placeholder can only accept a single value. WHERE zip IN (?)
won't work because you're (presumably) looking for more than one value (otherwise, why use IN
?).
You can, however, easily build a statement on the fly with the correct number of placeholders:
#!/usr/bin/env perl
use strict;
use warnings;
my @zips = (12345, 54321, 90210);
my $stmt = "SELECT `club_name`,`city`
FROM `table`
WHERE `public_gig` = 'y' AND `zip` IN ("
. join(', ', ('?') x @zips) . ')';
print "$stmt\n";
# Now just:
# my $sth = $dbh->prepare($stmt);
# $sth->execute(@zips);
Upvotes: 8
Reputation: 2536
Alternatively, if you don't mind using weird CPAN modules,
with DBIx::Perlish
you can just say:
my @results = db_fetch {
my $t: table;
$t->public_gig eq "y";
$t->zip <- @zips;
};
and it will do the right thing.
Full disclosure: I am the author of DBIx::Perlish
.
Upvotes: 1
Reputation: 1
You need to turn the array into a string of values seperated by commas. Try this :
my $zipcodes = join('\',\'',@zips);
SELECT `club_name`,`city` FROM `table` WHERE `public_gig` = 'y' AND `zip` IN ('".$zipcodes."');
Upvotes: -6
Reputation: 9346
I don't know perl too much, but this looks like a simple SQL problem: why don't you just build the SQL IN clause from your array? You should get something like
AND zip IN ('zip 1', 'zip 2', '...')
I doubt just adding an array in perl will create the right strings for the SQL string ...
Upvotes: -1