MySQL - Perl: Как использовать массив с IN в запросе выбора?(ГДЕ В (@array)) - PullRequest
4 голосов
/ 01 марта 2011

Это дополнение к моему решенному вопросу: как получить массив почтовых индексов в пределах x миль в perl

ОК, у меня есть массив @zips.Теперь я пытаюсь использовать его в таком запросе:

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')"

Но я не могу заставить его работать.(Я использую заполнители и такие, как вы видите в моей ссылке выше.)

Мне удалось заставить это работать:

$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

Но, по очевидным причинам и некоторому сходству точностиэто не совсем то, что я хочу.Просто хотел посмотреть, смогу ли я заставить что-то работать самостоятельно.

Почему я не могу заставить запрос работать с zip-массивом, используя IN ??Ничего не возвращается, и нет ошибки.

На самом деле в этом запросе гораздо больше, но я упустил все это, чтобы сократить его здесь.

Я попытался выяснить это с помощьюсебя.Очевидно, мои способности к обучению в течение дня близки к пику.

Спасибо за любую помощь.

Ответы [ 5 ]

8 голосов
/ 01 марта 2011

Все приведенные здесь примеры будут испорчены, если любое из ваших значений содержит одинарные кавычки, не используйте их.

Вместо этого (при условии, что $dbh является дескриптором базы данных для вашего соединения mysql):

my $zip_string = join q{,}, map $dbh->quote($_), @zips;

и интерполировать , что .

Или для чего-то приятного, но не наполовину такого, как DBIx :: Perlish: SQL ::Абстракт .

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.
6 голосов
/ 01 марта 2011

Это можно сделать с помощью заполнителей, вам просто нужно обойти ограничение, что каждый заполнитель может принимать только одно значение. WHERE zip IN (?) не будет работать, потому что вы (предположительно) ищете более одного значения (иначе, зачем использовать IN?).

Однако вы можете легко создать оператор на лету с правильным количеством заполнителей:

#!/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);
1 голос
/ 01 марта 2011

В качестве альтернативы, если вы не возражаете против использования странных модулей CPAN, с DBIx::Perlish вы можете просто сказать:

my @results = db_fetch {
   my $t: table;
   $t->public_gig eq "y";
   $t->zip  <-  @zips;
};

и все будет правильно.

Полное раскрытие : я являюсь автором DBIx::Perlish.

0 голосов
/ 01 марта 2011

Вам нужно превратить массив в строку значений, разделенных запятыми. Попробуйте это:

my $zipcodes = join('\',\'',@zips);
SELECT `club_name`,`city` FROM `table` WHERE `public_gig` = 'y' AND `zip` IN ('".$zipcodes."');
0 голосов
/ 01 марта 2011

Я не слишком много знаю Perl, но это выглядит как простая проблема SQL: почему бы вам просто не создать предложение SQL IN из вашего массива? Вы должны получить что-то вроде

И почтовый индекс ('zip 1', 'zip 2', '...')

Я сомневаюсь, что просто добавление массива в perl создаст правильные строки для строки SQL ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...