Связать 2 табличных значения в perl - PullRequest
1 голос
/ 21 сентября 2010

У меня есть две таблицы в базе данных mysql: CUSTOMER и GROUP

Таблица ЗАКАЗЧИКОВ:

  NAME |PHONE
  A    |222
  B    |333 
  C    |777
  D    |888
  E    |111
  F    |555

и т. Д.

Таблица GROUP имеет только 3 значения:

  GN   | NUM
  NEW  |807
  OLD  |455 
  INT  |504

Я бы хотел получить следующий результат:

  A, NEW, 807
  B, OLD, 455
  C, INT, 504
  D, NEW, 807
  E, OLD, 455
  F, INT, 504

и т. Д.

Таблица GROUP должна повторяться до конца таблицы CUSTOMER.

Вот мой код:

#!/usr/bin/perl

# PERL MODULES
use DBI;
use strict;
use warnings;


# MYSQL CONFIG VARIABLES
my $dsn = 'DBI:mysql:test:127.0.0.1';
my $tablename = "CUSTOMER";
my $user = "root";
my $pw = "xxxx";
# DEFINE A MySQL QUERY
my $myquery1 = "SELECT  NAME FROM $tablename";

# PERL CONNECT()
my $dbh = DBI->connect($dsn, $user, $pw);
# EXECUTE THE QUERY
my $getname = $dbh->prepare($myquery1); 
$getnum->execute(); 

my $getlogin = $dbh->prepare("select * from GROUP"); 
$getlogin->execute();
my($login, $password);
# FETCHROW ARRAY
while (my $name = $getname->fetchrow_array()) {

    while (my @row = $getlogin->fetchrow_array()) {
     my ($gn,$num) = @row;
        $login=$gn;
        $password=$num;

        print "$name\t\t $login \t\t $password \n";

    }


} 

Когда я выполняю свой код, я получаю:

  A NEW 807
  B OLD 455
  C INT 504

  DBD::mysql::st fetchrow_array failed: fetch() without execute() at ./main.pl line 29.

Как я могу это сделать? Любая помощь будет оценена.

Ответы [ 3 ]

3 голосов
/ 21 сентября 2010

Прежде всего, у вас есть опечатка - вы делаете $getnum->execute() не $getname->execute().Вы действительно выполнили точный код, который вставили?

После третьей итерации вы столкнулись с ошибкой, поскольку в таблице GROUP всего три строки данных.Вам нужно либо снова запустить цикл с новым запросом (выполнить execute() внутри первого цикла while, непосредственно перед началом второго), либо кэшировать все его данные в массив, который вы можете циклически повторять:

my $getname = $dbh->prepare($myquery1); 
my $getlogin = $dbh->prepare("select * from GROUP"); 

# FETCHROW ARRAY
$getname->execute(); 
while (my $name = $getname->fetchrow_array())
{
    $getlogin->execute();
    while (my @row = $getlogin->fetchrow_array())
    {
        my ($gn,$num) = @row;
        my $login=$gn;
        my $password=$num;

        print "$name\t\t $login \t\t $password \n";
    }
} 
0 голосов
/ 21 сентября 2010

Звучит так, будто вы просто хотите, чтобы строкам в таблице CUSTOMER присваивались чередующиеся значения, вращающиеся по таблице GROUP - и вам неважно, кто получит какое значение (или вы бы поместили ORDER в свои SELECT) .

Что бы я сделал: добавить столбец в таблицу GROUP со значениями 0, 1 и 2; присвоить таблице CUSTOMER инкрементный идентификатор; и присоединитесь к ним (CUSTOMER.id% 3 = GROUP.id). Это поворачивает значения GROUP вниз по таблице CUSTOMER так, как я думаю, именно так, как вы хотите.

ALTER TABLE `GROUP` ADD COLUMN id INT UNSIGNED NOT NULL, ADD INDEX idx_id (id);
UPDATE GROUP SET id=0 WHERE GN='NEW';
UPDATE GROUP SET id=1 WHERE GN='OLD';
UPDATE GROUP SET id=2 WHERE GN='INT';
ALTER TABLE `CUSTOMER` ADD COLUMN
    id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT;

Тогда достаточно одного ВЫБРАТЬ, чтобы получить нужные пары:

SELECT NAME, GN, NUM FROM `GROUP`, CUSTOMER WHERE GROUP.id = CUSTOMER.id % 3;

(P.S. Я предлагаю не называть в таблице ключевое слово SQL, например "GROUP", вам придется заключать его в кавычки каждый раз, когда вы его используете.)

0 голосов
/ 21 сентября 2010

Проблема в том, что вы звоните $getlogin->fetchrow_array после обработки всех элементов. Это происходит, когда цикл CUSTOMER выполняет вторую итерацию. Вы должны вызвать $getlogin->execute только в начале цикла CUSTOMER. Как это:

while (my $name = $getname->fetchrow_array()) {
    ## start new query each time we want to loop GROUP table
    my $getlogin = $dbh->prepare("select * from GROUP"); 
    $getlogin->execute();
    while (my @row = $getlogin->fetchrow_array()) {

Но это может снизить производительность скрипта. Я предлагаю вам выбрать все GROUP перед циклом CUSTOMER в массив и использовать его вместо загрузки данных из БД на каждой итерации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...