За последние 24 часа нас посетили 18465 программистов и 1606 роботов. Сейчас ищут 1246 программистов ...

MYSQLi - освобождение результата

Тема в разделе "MySQL", создана пользователем dos32, 10 мар 2013.

  1. dos32

    dos32 Активный пользователь

    С нами с:
    10 мар 2013
    Сообщения:
    2
    Симпатии:
    0
    помогите плиз, что-то я туплю. есть клас rpsql, который есть mysqli со своим конструктором.
    не получается по человечески вызвать 2 процедуры подряд :
    Код (Text):
    1.  
    2. $sql=new rpsql();
    3. $result=$sql->query("call select_navi_names($nGrpId,$nSubGrpId,$nVendorId)");
    4. $sqlRow = $result->fetch_array(MYSQLI_ASSOC);
    5. $result->close();
    6. $cGrpName=$sqlRow['GRP_NAME'];
    7. $cSubGrpName=$sqlRow['SUBGRP_NAME'];
    8. $cVendorName=$sqlRow['VENDOR_NAME'];
    9.  
    10.  
    11. if ($_SESSION['TovarId']>0){
    12.     $nTovarId=$_SESSION['TovarId'];
    13.     //$sql=new rpsql();
    14.     $result=$sql->query("call select_tovar_header($nTovarId)");
    15.     //printf("Ошибка: %s\n", $sql->error);
    16.     $sqlRow = $result->fetch_array(MYSQLI_ASSOC);
    17.     $cTovarName=$sqlRow['TOVAR_NAME'];
    почему мне $result->close(); не помогает ? (Commands out of sync; you can't run this command now ) / если раскомментировать //$sql=new rpsql(); то все работает, но некрасиво пересоединяться-то. В общем подскажите, где я ступил с использованием mysqli_result::free, судя по описанию после использования $result->close() должно все работать, чего я не догоняю подскажите плиз....
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    расскажи что за rpsql у тебя?
     
  3. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.251
    Адрес:
    там-сям
    могу предложить велосипед, который ездит :)
     
  4. dos32

    dos32 Активный пользователь

    С нами с:
    10 мар 2013
    Сообщения:
    2
    Симпатии:
    0
    да в общем-то почти чистый mysqli, ну и для дебуга вторая функция листинг результата там-же в классе вписана, хоть в нее $result и надо передавать, но это фигня:
    Код (Text):
    1. <?php
    2. class rpsql extends mysqli
    3. {
    4. //
    5. // подключимся сразу куда надо
    6. //
    7. function __construct() {
    8. $rphost = "192.168.13.101";
    9. $rpdb = "ххххххххх";
    10. $rpuser = "хххххххххххххххх";
    11. $rppassword = "хххххххххххххххххх";
    12.  
    13.     parent::__construct($rphost,$rpuser,$rppassword,$rpdb);
    14.         $this->query("set character_set_client='cp1251'");
    15.         $this->query("set character_set_results='cp1251'");
    16.         $this->query("set collation_connection='cp1251'");
    17.         $this->query("set names 'cp1251'");
    18.  
    19.    }
    20.  
    21.  
    22.  
    23. }
    24.  
    25.  
    26. // для отладки отдельныме функции
    27. function listtable($result)
    28. {
    29. // разберем результат
    30. $fieldcount = $result->field_count;
    31. printf( "<br>\n --------- листинг таблицы, полей ".$fieldcount);
    32.  
    33.   printf("\n<table border=1>\n");
    34.  
    35.     printf("<tr>\n");
    36.    
    37.     $fields=$result->fetch_fields();
    38.  
    39.         foreach ($fields as $val) {
    40.         printf('<th>'.$val->name.'</th>\n');
    41.     }
    42.  
    43.     printf("</tr>");
    44.  
    45.  
    46.   while ( $sqlRow = $result->fetch_array(MYSQLI_NUM)  )
    47.     {
    48.     printf( "<tr>");
    49.     foreach ($sqlRow as $fval) printf("<td>".$fval."</td>\n");
    50.     printf("</tr>\n");
    51.     }
    52.   printf("</table>\n");
    53. printf( "\n --------- конец листинга таблицы\n<br>");
    54. }
    55. ?>
    итого в принципе пользую mysqli, функции в call отдают один результат, потому и вызываю через query(). по сути real_query() и store_result() для одного резльтата будет то-же ?

    по идее после $result->close() должно-бы освобождаться и снова query() работать ? что-то не до конца я видимо в логику mysqli въехал, раньше просто mysql было, но теперь решил переваять на mysql5 и все брать проедуры. все пошло хорошо, но пересоздавать класс перед вторым query() некрасиво вместо того чтобы освободить.

    Добавлено спустя 20 минут 58 секунд:
    создал такой тест :
    Код (Text):
    1. <?php
    2. require_once('./lib/rpsql.class');
    3. $sql=new rpsql();
    4. //$result=$sql->query("select * from vendors");
    5. $result=$sql->query("call select_navi_names(5,1,3)");
    6. listtable($result);
    7. $result=$sql->query("select * from groups");
    8. listtable($result);
    9. ?>
    итого если выполняю последовательно 2 селекта, то даже без освобождения результатов все работает.
    комментирую первый селект и вместо него в query пишу call , и ситуация повторяется.
    итого после call результат так просто не освобождается ....

    Добавлено спустя 3 минуты 15 секунд:
    и добавление $result->close(); перед вторым запросом тоже не помогает

    Добавлено спустя 2 минуты 11 секунд:
    замена query на real_query тоже ничего не дает
    Код (Text):
    1. //$result=$sql->query("call select_navi_names(5,1,3)");
    2. $sql->real_query("call select_navi_names(5,1,3)");
    3. $result=$sql->store_result();
    4. listtable($result);
    5. $result->close();
    Добавлено спустя 29 минут 45 секунд:
    разобрался однако, так работает :

    Код (Text):
    1. <?php
    2. require_once('./lib/rpsql.class');
    3. $sql=new rpsql();
    4. //$result=$sql->query("select * from vendors");
    5. //$result=$sql->query("call select_navi_names(5,1,3)");
    6. $sql->real_query("call select_navi_names(5,1,3)");
    7. $result=$sql->store_result();
    8. listtable($result);
    9. $result->close();
    10.  
    11. while ($sql->more_results())    {
    12.     printf("-----ишшо было ----------\n");
    13.     $sql->next_result();
    14.     }
    15.  
    16. $result=$sql->query("select * from groups");
    17. listtable($result);
    18. ?>
    итого php считает что есть еще результат от call() ? в DBFORGE вижу что результат возвращается один, да и процедура на сервере такая :
    Код (Text):
    1.   SELECT groups.GRP_NAME
    2.   FROM
    3.     groups
    4.   WHERE
    5.     groups.GRP_ID = pGrpId
    6.   INTO
    7.     @cGrpName
    8.     ;
    9.  
    10.   SELECT subgrp.SUBGRP_NAME
    11.   FROM
    12.     subgrp
    13.   WHERE
    14.     subgrp.SUBGRP_ID = pSubgrpId
    15.   INTO
    16.     @cSubGrpName;
    17.  
    18.   SELECT vendors.vendor_name
    19.   FROM
    20.     vendors
    21.   WHERE
    22.     vendors.vendor_id = pVendorId
    23.   INTO
    24.     @cVendorName;
    25.  
    26.  
    27.   SELECT ifnull(@cGrpName, '') AS GRP_NAME
    28.      , ifnull(@cSubGrpName, '') AS SUBGRP_NAME
    29.      , ifnull(@cVendorName, '') AS VENDOR_NAME
    30.      
    31. ;
    по сути три выборки в переменные и выдача селектом одной строкой ....

    т.е. в mysqli после вызова процедуры через call всегда в цикле прверять more_results() нужно, даже если ты уверен, что результат был один ? или я опять что-то не допонял ?

    Добавлено спустя 13 минут 48 секунд:
    хотя ... попытка зафетчить второй резльтат ничего нет дает, пусто там, т.е. что , принипиально указатель списка результатов обзательно дернуть ?

    итого дополнил класс еще одно функцией для этого, дабы в коде циклов не писать :

    Код (Text):
    1. //освободить лишние результаты
    2. function clear(){
    3.     while ($this->more_results())   {
    4.     $this->next_result();
    5.     }
    6. }
    но сдается мне что это таки изврат от недопонимания мной чего-то ...
    итого на выходе работает :
    Код (Text):
    1. <?php
    2. require_once('./lib/rpsql.class');
    3. $sql=new rpsql();
    4. //$result=$sql->query("select * from vendors");
    5. //$result=$sql->query("call select_navi_names(5,1,3)");
    6. $sql->real_query("call select_navi_names(5,1,3)");
    7. $result=$sql->store_result();
    8. listtable($result);
    9. $result->close();
    10. $sql->clear();
    11.  
    12. $result=$sql->query("select * from groups");
    13. listtable($result);
    14. ?>
     
  5. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Велосипедисты епт =)))
    Вы финишируете когда-нибудь?))