使用 Perl 从 SQL Join 获取结果



这有效

TABLE users
userid  firstname   lastname
1        JOHN          DEO
2        JANE          DEO
TABLE msg
msg_id    msg_from     msg_to      received   
1         userid(1)    userid(2)   null       
$janedeo_id = 2;

my $data = $DBH->prepare("SELECT SND.userid, SND.firstname, SND.lastname
FROM msg as M
JOIN users as SND 
ON SND.userid = M.msg_from
WHERE M.msg_to = ? 
AND M.received IS NULL");
$data->execute($janedeo_id);
while (my $row = $data->fetchrow_hashref) {
foreach $row ( @$data) {
($userid, $snd_firstname, $snd_lastname) = @$data;
}
}
my $templ    = <<START_HTML;
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1
+" />
<title>Untitled Document</title>
</head>
<body>
[% FOREACH name IN list %]
<p>userid    [% name.0 %] </p>
<p>firstname [% name.1 %] </p>
<p>lastname  [% name.2 %] </p>
[% END %]
</body>
</html>
START_HTML
$template->process ($templ, { list => @$data })
or die $template->error;

这行不通。 当我尝试添加年龄城市国家和结果时,它失败了 无法正常工作

TABLE users
userid   firstname    lastname
1         JOHN         DEO
2         JANE         DEO
TABLE msg
msg_id    msg_from     msg_to      received   age  city  country
1         userid(1)    userid(2)   null       26   any   any
$janedeo_id = 2;

my $data = $DBH->prepare("SELECT SND.userid, SND.firstname, SND.lastname, SND.age, SND.city, SND.country
FROM msg as M
JOIN users as SND 
ON SND.userid = M.msg_from
WHERE M.msg_to = ? 
AND M.received IS NULL");
$data->execute($janedeo_id);
while (my $row = $data->fetchrow_hashref) {
foreach $row ( @$data) {
($userid, $snd_firstname, $snd_lastname, $snd.age, $snd.city, $snd.country) = @$data;
}
}
my $templ    = <<START_HTML;
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>Untitled Document</title>
</head>
<body>
[% FOREACH name IN list %]
<p>userid    [% name.0 %] </p>
<p>firstname [% name.1 %] </p>
<p>lastname  [% name.2 %] </p>
<p>city      [% name.3 %] </p>
<p>age       [% name.4 %] </p>
<p>country   [% name.5 %] </p>
[% END %]
</body>
</html>
START_HTML
$template->process ($templ, { list => @$data })
or die $template->error;

当我尝试将城市年龄国家/地区添加到表味精并打印出来时,我无法获得结果。 我只是得到空白的回应。 甚至脚本只是打印错误。 在数据库中找不到任何内容。 所以我只是困惑我不知道问题

这真的很奇怪:

while (my $row = $data->fetchrow_hashref) {
foreach $row ( @$data) {
($userid, $snd_firstname, $snd_lastname, $snd.age, $snd.city, $snd.country) = @$data;
}
}

从结果中获取一行作为哈希引用。你比迭代@$data这是一个语句句柄 - 这不起作用。在循环中使用提取的$row

此外,.是串联运算符。你说$snd.city是什么意思?

您可以使用 Data::D umper 查看返回的结构:

use Data::Dumper;
...
while (my $row = $data->fetchrow_hashref) {
print Dumper $row;
}

下面是一个独立示例:

#!/usr/bin/perl
use warnings;
use strict;
use DBI;
use Template;
# Fake the database
my $dbh = 'DBI'->connect('dbi:SQLite:dbname=:memory:', "", "");
$dbh->do('CREATE TABLE USERS (id INT, firstname VARCHAR(20), lastname VARCHAR(20), age INT, city VARCHAR(20), country VARCHAR(20))');
$dbh->do('INSERT INTO USERS VALUES(1, "John", "Doe", 30, "Mumbai", "India")');
$dbh->do('INSERT INTO USERS VALUES(2, "Jane", "Doe", 20, "New York", "USA")');
$dbh->do('CREATE TABLE msg (id INT, msg_from VARCHAR(20), msg_to VARCHAR(20), received BOOL)');
$dbh->do('INSERT INTO msg VALUES (1, 2, 1, NULL)');
# Template.
my $templ = << '__HTML__';
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>Untitled Document</title>
</head>
<body>
[% FOREACH user IN list %]
<p>userid    [% user.id %] </p>
<p>firstname [% user.firstname %] </p>
<p>lastname  [% user.lastname %] </p>
<p>city      [% user.city %] </p>
<p>age       [% user.age %] </p>
<p>country   [% user.country %] </p>
[% END %]
</body>
</html>
__HTML__

my $data = $dbh->prepare(<< '__SQL__');
SELECT u.id, u.firstname, u.lastname, age, u.city, u.country
FROM msg as m
JOIN users as u
ON u.id = m.msg_from
WHERE m.msg_to = ?
AND m.received IS NULL
__SQL__
$data->execute(1);
my @output;
while (my $row = $data->fetchrow_hashref) {
push @output, $row;
}
'Template'->new->process ($templ, { list => @output })
or die $templ->error;

你看起来非常非常困惑。我不认为您实际上向我们展示了您正在运行的代码。看看这个代码:

my $data = $DBH->prepare("SELECT SND.userid, SND.firstname, 
SND.lastname
FROM msg as M
JOIN users as SND 
ON SND.userid = M.msg_from
WHERE M.msg_to = ? 
AND M.received IS NULL");
$data->execute($janedeo_id);
while (my $row = $data->fetchrow_hashref) {
foreach $row ( @$data) {
($userid, $snd_firstname, $snd_lastname,
$snd.age, $snd.city, $snd.country) = @$data;
}
}

这是您的第一个代码示例 - 您声称有效的代码。但它不可能奏效。

你有一个名为$data的变量,其中包含您的 DBI 语句句柄(我知道这一点,因为它是从$DBH->prepare()调用返回的(。更常见的是将此变量称为$sth

您正确地在此对象上调用execute(),然后开始循环调用fetchrow_hashref()。您将获得的哈希引用存储在名为$row的变量中。目前为止,一切都好。

但随后一切都出错了。

您忽略您拥有的哈希引用,并用存储在$data中的数据覆盖它。但是$data中没有数据 - 它是一个语句句柄。您将其视为数组引用(@$data(,但它不是数组引用,因此这将引发致命的运行时错误。

然后,您忽略输入$row的第二个值,并切换到使用单个变量来存储从数据库中返回的数据。再一次,您将$data视为数组引用,再一次,它将不起作用,并将引发致命的运行时错误。哦,你正在使用变量名(例如,$snd.age(,这在Perl中是无效的,几乎肯定会给你一个语法错误。

通过声称此代码有效,您是在浪费我们的时间。它不起作用。它甚至不编译。我们很乐意在这里帮助人们,但您需要向我们展示我们可以运行的实际代码。

我不知道你的编程背景是什么。但是为了在这个职业中取得成功,你将不得不更加关注细节。

我通过做解决了这个问题

SELECT SND.userid, SND.firstname, SND.lastname, M.age, M.city, M.country
FROM msg as M
JOIN users as SND 
ON SND.userid = M.msg_from
WHERE M.msg_to = 'userid -1'
AND M.received IS NULL

最新更新