使用perl从sql join获取结果

时间:2018-10-05 10:27:37

标签: perl

这有效

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;
我尝试将城市年龄国家/地区添加到表味精中并打印出来时,

am无法获得结果。只是一片空白。即使脚本只是打印错误。在数据库中找不到任何内容。所以很困惑,我不知道问题所在

3 个答案:

答案 0 :(得分:0)

这真的很奇怪:

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::Dumper查看返回的结构:

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;

答案 1 :(得分:0)

您似乎非常困惑。我认为您实际上并未向我们展示您正在运行的代码。看这段代码:

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中无效,并且几乎可以肯定会给您语法错误。

声称此代码有效,就是在浪费我们的时间。没用它甚至不编译。我们非常乐意为您提供帮助,但是您需要向我们展示可以运行的实际代码。

我不知道您的编程背景是什么。但是要想在这个职业上取得成功,您将不得不更加注重细节。

答案 2 :(得分:-1)

我通过解决此问题

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