正如其他人提到的:
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 组)。
您需要将会话替换为 (?)BEFORE 您执行 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。