Forum Webscript.Ru

Программирование => Perl => Тема начата: koliama от 26 Мая 2004, 15:42:16

Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 15:42:16
Доброго дня всем.
Сразу хочу сказать, что в перле я новичек). Делаю следующее:
sub all_traf
    {
        $sth = $dbh -> prepare("SELECT sum(fsize)/1024/1024 AS Summa FROM $table;");
        $sth -> execute();
        while (my $summa = $sth->fetchrow_array())
            {
            }
              $q->table({-border=>1,
                        -width=>300,
                        -align=>CENTER,
                        -bgcolor=>\'#666666\'},
                        $q->caption(\'Summa vsego trafica\'),
                        $q->Tr([$q->td({-width=>\'50%\'},[\'All trafic\',$summa])]));

        $sth->finish;
        $dbh->disconnect();
    }
и далее вызываю эту подпрограмму в теле осн. программы. В итоге отработки данного модуля я хочу получить таблицу из одной строки и двух ячеек
                All trafic     $summa
таблица выводится, а значение переменной $summa - нет. Вижу только пустую ячейку... Получается очень странное дело - переменная $summa видна только в теле цикла.
Помогите разобраться. :(
Название: Потеря переменной после отработки цикла while
Отправлено: vladsu от 26 Мая 2004, 15:49:57
Читайте об области видимости переменных. А пока сделайте так
sub all_traf
{
my $summa;
$sth = $dbh -> prepare("SELECT sum(fsize)/1024/1024 AS Summa FROM $table");
$sth -> execute();
while ($summa = $sth->fetchrow_array())
{
}
$q->table({-border=>1,
-width=>300,
-align=>CENTER,
-bgcolor=>\'#666666\'},
$q->caption(\'Summa vsego trafica\'),
$q->Tr([$q->td({-width=>\'50%\'},[\'All trafic\',$summa])]));

$sth->finish;
$dbh->disconnect();
}
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 16:05:23
Уважаемый vladsu
последовал вашему совету - результат прежний. :( После выполнения цикла переменная $summa не видна.
Может быть возможно обойтись без цикла для задания скалярной переменной $summa значения полученного после отработки запроса? все равно запрос возвращает единственное значение....
Название: Потеря переменной после отработки цикла while
Отправлено: vladsu от 26 Мая 2004, 16:09:14
Я плохо знаю ДБАй, но можно попробовать написать

$summa = ( $sth->fetchrow_array )[0];
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 16:17:00
хм.. результат то тот же. в цикля я могу с переменной делать все что угодна, вне его - нет...
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 16:24:33
Оказывается здесь цикл и не нужен. достаточно просто поставить условие

if ($summa = $sth->fetchrow_array())
{
печатаем таблицу
}

сенкс за ответы. :)
Название: Потеря переменной после отработки цикла while
Отправлено: vladsu от 26 Мая 2004, 16:25:05
Вы уверенны что Вы эту строку

$summa = ( $sth->fetchrow_array )[0];

написали в место

while ($summa = $sth->fetchrow_array())
{
}
?
Название: Потеря переменной после отработки цикла while
Отправлено: Chs от 26 Мая 2004, 16:28:29
vladsu
Он уверен.
После этого цикла сумма всегда будет 0.
while ($summa = $sth->fetchrow_array()[0])
{
}
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 16:33:33
Chs
А можно поподробнее про ноль после цикла. Интуитивно я понимаю почему, но объяснить не могу...?
Название: Потеря переменной после отработки цикла while
Отправлено: Chs от 26 Мая 2004, 16:50:02
В условии цикла присваивание.
Соответственно пока условие истинно крутится цикл, а выход из него когда условие не выполняется, но значение-то все равно присваеевается переменной при проверке условия.
Так понятно?
Название: Потеря переменной после отработки цикла while
Отправлено: vladsu от 26 Мая 2004, 16:50:39
Цитировать
Chs:
Он уверен.
После этого цикла сумма всегда будет 0.
while ($summa = $sth->fetchrow_array()[0])
{
}

Вы что-то путаете, я не предлагал использовать цикл
я предложил использовать

sub all_traf {

    $sth = $dbh -> prepare("SELECT sum(fsize)/1024/1024 AS Summa FROM $table");
    $sth -> execute();

    my $summa = ($sth->fetchrow_array)[0];

    $q->table({-border=>1,
               -width=>300,
               -align=>CENTER,
               -bgcolor=>\'#666666\'},
    $q->caption(\'Summa vsego trafica\'),
    $q->Tr([$q->td({-width=>\'50%\'},[\'All trafic\',$summa])]));

    $sth->finish;
    $dbh->disconnect();
}
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 16:55:53
Chs
Семен Семеныч..... Ну конечно.
биг сенкс :)
vladsu
Кстати с вашим вторым советом
my $summa = ($sth->fetchrow_array)[0];
не работает.
выдает что-то типа
$summa = Array(0x........)
Название: Потеря переменной после отработки цикла while
Отправлено: Chs от 26 Мая 2004, 16:57:35
Цитировать
Вы что-то путаете, я не предлагал использовать цикл

http://forums.webscript.ru/showthread.php?s=&postid=109038#post109038
Да???:)
Название: Потеря переменной после отработки цикла while
Отправлено: vladsu от 26 Мая 2004, 17:14:16
А мне показалось, что Ваш пост
Цитировать
Chs:
Он уверен.
После этого цикла сумма всегда будет 0.
while ($summa = $sth->fetchrow_array()[0])
{
}

был ответом на мой вопрос
Цитировать
vladsu:
Вы уверенны что Вы эту строку

$summa = ( $sth->fetchrow_array )[0];

написали в место

while ($summa = $sth->fetchrow_array())
{
}
?



Цитировать
koliama:
vladsu
Кстати с вашим вторым советом...

Странно, а у меня это

my $sth = $dbh -> prepare("SELECT sum($fild_name)/1024/1024 AS Summa FROM $table");
   $sth -> execute();

my $summa = ($sth->fetchrow_array)[0];

print $summa;

$sth->finish;
$dbh->disconnect();

работает, как надо.
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 17:28:29
vladsu

?? а у меня нет....
Название: Потеря переменной после отработки цикла while
Отправлено: vladsu от 26 Мая 2004, 17:37:00
Цитировать
koliama:
?? а у меня нет....

может это потому, что у Вас в
$sth = $dbh -> prepare("SELECT sum(fsize)/1024/1024 AS Summa FROM $table[b];[/b]");
стоит лишняя точка с запятой?
Название: Потеря переменной после отработки цикла while
Отправлено: Phoinix от 26 Мая 2004, 17:45:01
vladsu
И не только это...


koliama
Функция SUM используется в операторах GROUP BY, которого я тут как бы не наблюдаю. Результатом выполнения запроса, является error...
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 17:46:05
почему лишняя? ; - это объяснение мускулу, что запрос надо выполнять.
Название: Потеря переменной после отработки цикла while
Отправлено: NeoNox от 26 Мая 2004, 17:48:57
Цитировать
koliama:
это объяснение мускулу, что запрос надо выполнять.

бегом читать perldoc DBI
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 17:52:29
NeoNox
Вы считаете, что точку с запятой в конце запроса ставить нельзя? Я думаю, что от этого ничего страшного не случится. А в некоторых случаях может помочь...
Но в документации действительно не ставится точка с запятой в конце запроса. Завтра обязательно попробую убрать ее.
Хотя, имхо, не в этом дело.

To
Phoinix
Совсем не обязательно :) Я же использую конструкцию
AS....
Название: Потеря переменной после отработки цикла while
Отправлено: vladsu от 26 Мая 2004, 17:53:38
Цитировать
Phoinix:
Функция SUM используется в операторах GROUP BY, которого я тут как бы не наблюдаю. Результатом выполнения запроса, является error...


Не верно, GROUP BY нужен если будет более одной колонки.

Цитировать
koliama:
почему лишняя? ; - это объяснение мускулу, что запрос надо выполнять.

perldoc DBI
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 17:55:54
Я читал доку к данному модулю. Нигде ЯВНО не сказано, что ; ставить нельзя.
Название: Потеря переменной после отработки цикла while
Отправлено: vladsu от 26 Мая 2004, 17:56:16
Цитировать
koliama:
Завтра обязательно попробую убрать ее.
Хотя, имхо, не в этом дело.

И заодно не забудьте поставить, в начале программы
use strict;
!!!
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 18:00:27
vladsu
хм.. вот с этим проблемы. уже пробовал, но скрипт просто отказался работать..
Название: Потеря переменной после отработки цикла while
Отправлено: Phoinix от 26 Мая 2004, 18:02:18
koliama
Цитировать
Я же использую конструкцию AS


Вот это как раз таки не причем, AS - ключевое слово присвоения...

Да, я не обратил внимание, что суммирование может вестись по всей таблице...

Цитировать
А в некоторых случаях может помочь

Интрересно, в каких случаях это помогает... ;)
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 18:05:33
Phoinix
а вы попробуйте убрать AS - ..... :)
в каких еще не знаю :) но она и не мешает.
Название: Потеря переменной после отработки цикла while
Отправлено: Phoinix от 26 Мая 2004, 18:11:53
koliama
Попробовал и что дальше?

SELEST SUM(id) AS Summa FROM table;

result:

------------------
Summa
------------------
8646
------------------



SELEST SUM(id) FROM table;

result:

------------------
SUM(id)
------------------
8646
------------------

И в чем же разница, если ты данные выбираешь не в хеш, а в обычный массив?
Название: Потеря переменной после отработки цикла while
Отправлено: vladsu от 26 Мая 2004, 18:13:52
Цитировать
koliama:
хм.. вот с этим проблемы. уже пробовал, но скрипт просто отказался работать..

Не вижу смысла продолжать дальнейшую дискуссию, пока Вы не избавитесь от проблем на которые указывает "стрикт"!

Цитировать
koliama:
но она и не мешает.

Я бы не стал на Вашем месте так категорично это утверждать, тем более, что Вы не правы.
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 26 Мая 2004, 18:18:41
vladsu
а не подскажете, где можно почитать про ограничения, которые накладывает этот оператор?
Название: Потеря переменной после отработки цикла while
Отправлено: vladsu от 26 Мая 2004, 18:26:57
Цитировать
koliama:
а не подскажете, где можно почитать про ограничения, которые накладывает этот оператор?

Оно называется "прагмой". Минимально
perldoc strict
Только Вам не об ограничениях нужно читать, а нужно ее вставить в Ваш код и пытаться исправить все ошибки на которые она указывает, будут проблемы, обращайтесь в форум или можно на прямую ко мне в асю.
Название: Потеря переменной после отработки цикла while
Отправлено: Phoinix от 26 Мая 2004, 18:39:47
koliama
perldoc strict


А еще для начала выведи на экран свой запрос:

print "SELECT sum(fsize)/1024/1024 AS Summa FROM $table;";

после чего перепиши его с экрана в MySQL manager и попробуй выполнить... посмотри результат...

потом как сказал NeoNox читаем ман по DBI:
Как не странно, fetchrow_array возвращает массив, но никак не переменную (array - ничего не говорит???), попытка приравнять переменную к массиву приводит к тому то возвращается количество элементов(!) массива, в данном случае 1. То что конструкция
Цитировать
my $summa = ($sth->fetchrow_array)[0];
выводит ссылку на массив ("что-то типа" - это ссылка) - ошибка...

Курим доки...
Название: Потеря переменной после отработки цикла while
Отправлено: koliama от 27 Мая 2004, 10:35:29
Phoinix
Ессно такая конструкция работать не будет. Если ее набирать в консоли или через MySql Front например ...
Но в cgi скрипте она отрабатывает. Я вчера весь вечер переводил perldoc DBI - еще раз повторюсь - явно нигде не сказано, что ; ставить нельзя.
Тем более что в моем скрипте такая конструкция работает и прагма strict на нее не указывает (как на ошибку)
Насчет возвращения количества элементов массива ты тоже не прав. Строка
my $summa = ($sth->fetchrow_array)[0];
присваевает переменной именно значение первого элемента массива...
vladsu
А как можно в асю стукнуться? В смысле, где номер взять?
Название: Потеря переменной после отработки цикла while
Отправлено: Phoinix от 27 Мая 2004, 13:30:58
koliama
[OFF]У меня складывается впечатление, что автор сам не понимает что делает...[/OFF]
Цитировать
Кстати с вашим вторым советом
my $summa = ($sth->fetchrow_array)[0];
не работает.
выдает что-то типа
$summa = Array(0x........)


Вот это что-то типа выдавать должно не ссылку на массив, а элемент оного, ARRAY(xxxx) - есть ссылка на массив...

Цитировать
Ессно такая конструкция работать не будет. Если ее набирать в консоли или через MySql Front например ...
Но в cgi скрипте она отрабатывает. Я вчера весь вечер переводил perldoc DBI - еще раз повторюсь - явно нигде не сказано, что ; ставить нельзя.


Какая конструкция??? Поробуй выполнить свой запрос не в скрипте, а консоли и посмотри результат... При этом сначала выведи запрос на экран, причем в том месте скрипта где ты его пытаешься выполнить!
90% вероятность того что переменная $table у тебя не определена! Соответственно запрос не верен! Но конечно, логи ошибок, мы так и не удосужились посмотреть и увидеть свою ошибку!

еще раз рекомендуется использовать strict, а в идеале еще и warning (-w)