Выполнить запрос DBI с конкатонированной строкой - PullRequest
1 голос
/ 09 ноября 2010

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ - Очень новый для Perl -

Мне нужно передать составленную строку сессий в подготовленный запрос, который выглядит следующим образом:

my $uniqueSessions="SELECT DISTINCT  SESSION
                    FROM   $table";

my $queryUniques = $connect->prepare($uniqueSessions);
$queryUniques->execute();
$queryUniques->bind_columns(\$session);

my $query="SELECT   session, action
           FROM     $table
           WHERE    session
           IN       (?)
           ORDER BY session, id";

my $queryPrep = $connect->prepare($query);

while($queryUniques->fetch()) {
    if($counter == 1) {
        $sessionString = "'" . $session . "'";
    } else {
        $sessionString = $sessionString . ", '" . $session . "'";
    }

    $counter++;
    if(($counter % 5) == 0) {
        $counter = 1;
        $queryPrep->execute($sessionString);
        my @test = $queryPrep->fetchall_arrayref();
    }
} 

Но это ничего не возвращает,и я попробовал точный запрос в моем клиенте БД, и он работает, какие-нибудь мысли?

РЕДАКТИРОВАТЬ: Извините, кажется, слишком много вырезал Я отредактировал код, чтобы убедиться, что вся информация присутствовала;

Возвращаемая строка - это сеансы, заключенные в одинарные кавычки и между запятой.

Ответы [ 3 ]

1 голос
/ 09 ноября 2010

Как уже упоминали другие:

use strict;
use warnings;

Кроме того, каждый раз, когда вы делаете вызов DBI, вы должны делать это:

if ($sth->err()) {
  die "ERROR: " . $sth->errstr() . "\n";
}

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

Я немного упростил вашу программу:

use strict;
use warnings;

use DBI;

my $connect = DBI->connect("$connectString", "$user", "$id");

if (not $connect) {
die qq(connection error\n);
}

my $table = "session";
my $uniqueSessions = "SELECT DISTINCT  SESSION
        FROM   $table";

print qq(\$uniqueSessions = "$uniqueSessions"\n);

my $queryUniques = $connect->prepare($uniqueSessions);
if ($queryUniques->err()) {
die "ERROR: " . $queryUniques->errstr() . "\n";
}
$queryUniques->execute();
if ($queryUniques->err()) {
die "ERROR: " . $queryUniques->errstr() . "\n";
}

my $session;
$queryUniques->bind_columns(\$session);

my $counter = 1;
my $sessionString;
while(my $hashref = $queryUniques->fetch()) {
print "Fetching Row\n";
if($counter == 1) {
    $sessionString = "'" . $session . "'";
} else {
    $sessionString = $sessionString . ", '" . $session . "'";
} 
$counter++;
}
if ($queryUniques->err()) {
print "ERROR = " . $queryUniques->errstr . "\n";
}

print "$sessionString\n";

Я в основном взял второй запрос и кое-что исправил. Последняя строка выводит $sessionString, который представляет собой список всех ваших сеансов, разделенных кавычками. Эта часть сработала.

Вторая часть, где вещи становятся странными. Вы берете $sessionString и передаете его как оператор SQL. Если только я чего-то не вижу, $sessionString - это просто список сеансов, а не оператор SQL сам по себе.

Как я уже говорил, проверяйте наличие ошибок при каждом вызове DBI и проверяйте, не ошиблись ли вы где-нибудь.

Вы также можете добавить такую ​​строку:

print qq(DEBUG: SQL Query = '$sqlStatement'\n);

перед тем, как вы запустите $sth->prepare($sqlStatement) и таким образом, вы сможете увидеть, каков ваш оператор SQL.


Проблема

Похоже, вы готовите второй запрос, прежде чем выясните, каким должен быть (?) (я полагаю, это ваша группа $ sessionString).

Вам нужно заменить сеансы на (?) ДО , когда вы выполняете DBI-> prepare ().

Примерно так ( не проверено ):

(my $sessionQuery = $query) =~ s/\(\?\)/$sessionString/;
my $querySth = $connect->prepare($sessionQuery);
$querySth->execute();
my @test = $queryPrep->fetchall_arrayref();

Помните, что qq() синтаксис цитирования - ваш друг. Я часто этим пользуюсь:

print qq(DEBUG: \$foo = "$foo"\n);

А иногда я просто копирую и вставляю заявление, а затем цитирую его:

print qq(DEBUG: while (my $foo = foobar($bar)) };\n);

Удивительно, сколько ошибок я могу уловить таким образом. Затем я могу найти DEBUG: в моей программе и удалить эти строки.

Не забывайте писать свои программы по очереди, посмотрите, сможете ли вы $sessionString работать. Затем попробуйте посмотреть, можете ли вы заменить это на $query, а затем попробуйте выполнить вычисленный запрос.

Perl - хороший и мощный язык, но синтаксис иногда может быть немного хитрым, особенно если вы не используете объектно-ориентированный Perl.

0 голосов
/ 09 ноября 2010

Откуда приходит $ session ?? В первую очередь предлагаю поставить

use strict;

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

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

my @sessions = ();

# perhaps you meant this?
while(my $session = $queryUniques->fetch()) {
    push @sessions, $session

    if((scalar @sessions) % 5 == 0) {
        my $sessionString = join ",", map { "'$_'" } @sessions;
        @sessions = ();
        $queryPrep->execute($sessionString);
        my @test = $queryPrep->fetchall_arrayref();
    }
} 
0 голосов
/ 09 ноября 2010

Просто задайте себе два вопроса:

1) Какое значение $sessionString непосредственно перед вызовом execute()?

2) Какое возвращаемое значение у метода execute?
Попробуйте:

$queryPrep->execute($sessionString) or die $queryPrep->errstr;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...