使用concatonated String执行DBI查询

时间:2010-11-09 13:44:16

标签: perl string concatenation dbi

免责声明 - 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 个答案:

答案 0 :(得分:1)

正如其他人所说:

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。

答案 1 :(得分:0)

问自己两个问题:

1)在$sessionString来电之前,execute()的价值是多少?

2)execute方法的返回值是什么? 尝试:

$queryPrep->execute($sessionString) or die $queryPrep->errstr;

答案 2 :(得分:-1)

$ session来自哪里? 首先,我建议把

use strict;

在你的perl程序中,这样你就可以在它们发生之前捕获许多容易的bug。

问题的关键在于您尝试构建用逗号分隔的单引号字符串。在这种情况下,我会使用一个数组来存储您需要的值,然后在发出查询之前加入它们。例如:

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();
    }
}