получение результатов из sql join с использованием perl - PullRequest
0 голосов
/ 05 октября 2018

это работает

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;

Не удается получить результаты, когда я пытаюсь добавить страну города возраста в таблицу MSG и распечатать их.Я просто получаю пустой ответ.даже скрипт просто печатает ошибку.ничего не могу найти в базе данных.так что я просто сбит с толку, я не знаю проблемы

Ответы [ 3 ]

0 голосов
/ 05 октября 2018

я исправил это, выполнив

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
0 голосов
/ 09 октября 2018

Ты выглядишь очень, очень растерянным.Я не думаю, что вы на самом деле показывает нам код, который вы запускаете.Посмотрите на этот код:

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 и которые почти наверняка приведут к синтаксической ошибке.

Утверждая, что этот код работает, вы тратите впустуювремя.Не работаетЭто даже не компилируется.Мы очень рады помочь людям здесь, но вам нужно показать нам реальный код, который мы можем запустить.

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

0 голосов
/ 05 октября 2018

Это действительно странно:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...