Xpoint
   [напомнить пароль]

получения результата SQL-запроса генерируемого хранимой процедурой

Метки: [без меток]
2007-06-11 20:20:48 [обр] svem[досье]
сообщение промодерировано

Вопрос:
как получить результат SQL-запроса генерируемого хранимой процедурой?
т.е. имеем хран. процедуру например:

PROCEDURE `get_object_event`(IN _objectId INT)
BEGIN

 SELECT `event_id`, `event`.`remark`, `state`.`name` state_name, `event`.`date`, `user`.`login` `user`
 
 FROM `event`
 
 LEFT JOIN `state` USING(`state_id`)
 LEFT JOIN `user` ON `user`.`user_id` = `event`.`user_id`
 
 WHERE `object_id` = _objectId
 ORDER BY `event`.`date` ASC;

END

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

вот mysql_query ругается: "PROCEDURE get_object_event can't return a result set in the given context"...

  1. Возможно ли средствами библиотеки mysql получить выборку а php?

Идем далее... берем библиотеку mysqli. Ура все работает!!! mysqli_query и далее mysqli_fetch_accos получаем желаемый результат.
Но! После первого запроса
$this->dbh->query("CALL get_object_event('30'));
Делаем второй запрос, например
$this->dbh->query("CALL get_object_event('32'));,
или другой на получение выборки хр.пр.

получаем ошибку сервера mysql:
"Commands out of sync; you can't run this command now"

Читаем доки:
A.2.12. Ошибка в клиенте Commands out of sync
Если получена ошибка Commands out of sync; you can't run this command now в клиентском коде, то клиентские функции вызываются в неправильном порядке!

Это может произойти, например, если используется mysql_use_result() и делается попытка выполнить новый запрос до того, как вызвана mysql_free_result(), или если клиент пытается выполнить два возвращающих данные запроса без обращения к mysql_use_result() либо mysql_store_result() в промежутке между ними.

Ок, делаем как надо: в начале запрос, затем извлекаем результат

public function next()
   {
      if ($this->done)
      {
         return false;
      }
      $offset = $this->currIndex + 1;
      if (empty($this->result[$offset]))
      {
         $row = $this->stmt->fetch_assoc();
         if (!$row)
         {
            [color=red]print "=".$this->stmt->free_result();[/color]
            $this->done = true;
            return false;
         }
         $this->result[$offset] = $row;
         ++$this->rowIndex;
         ++$this->currIndex;
         return $this;
      }
      else
      {
         ++$this->currIndex;
         return $this;
      }
   }

знак "=" есть на экане, т.е. [php]$this->stmt->free_result()[/php] выполняется.
И все-равно, один фиг. такая же ошибка по второго mysqli_query (((

блин, может не так mysqli юзаю?... Кто-нить встречался с такой проблемой?

Короче вопрос остается открытым
Вопрос:
как получить результат SQL-запроса генерируемого хранимой процедурой? или несколько на странице?

спустя 2 часа 13 минут [обр] Евгений[досье]

26.4.14: Can MySQL 5.0 stored routines return result sets?

Stored procedures can, but stored functions cannot. If you perform an ordinary SELECT inside a stored procedure, the result set is returned directly to the client. You need to use the MySQL 4.1 (or above) client-server protocol for this to work. This means that — for instance — in PHP, you need to use the mysqli extension rather than the old mysql extension.

спустя 5 минут [обр] Евгений[досье]

Вот что пишут на MySQL Reference Site:

http://dev.mysql.com/doc/refman/5.0/en/stored-procedures.html

For programs written in a language that provides a MySQL interface, there is no native method for directly retrieving the results of OUT or INOUT parameters from CALL statements. To get the parameter values, pass user-defined variables to the procedure in the CALL statement and then execute a SELECT statement to produce a result set containing the variable values. The following example illustrates the technique (without error checking) for a stored procedure p1 that has two OUT parameters.

mysql_query(mysql, "CALL p1(@param1, @param2)");
mysql_query(mysql, "SELECT @param1, @param2");
result = mysql_store_result(mysql);
row = mysql_fetch_row(result);
mysql_free_result(result);

After the preceding code executes, row[0] and row[1] contain the values of @param1 and @param2, respectively.

To handle INOUT parameters, execute a statement prior to the CALL that sets the user variables to the values to be passed to the procedure.

спустя 2 часа 10 минут [обр] svem[досье]
сообщение промодерировано

Да это понятно.
Но...

$link = mysqli_connect("localhost", "project", "project2323", "proj");

$result = mysqli_query($link, "CALL get_object_event('30')");
while($row = mysqli_fetch_assoc($result)) print_r($row);
mysqli_free_result($result);


$result = mysqli_query($link, "CALL get_object_event('39')");

print_r(mysqli_error($link));

Повторный запрос даёт ошибку:
Commands out of sync; you can't run this command now

Именно, если запрос - хранимая процедура... хотя если запрос простой, то все работает нормально....
Так же:

$link = mysqli_connect("localhost", "project", "project2323", "proj");

$result = mysqli_query($link, "CALL get_object_event('30')");
while($row = mysqli_fetch_assoc($result)) print_r($row);
mysqli_free_result($result);
mysqli_close($link);

$link = mysqli_connect("localhost", "project", "project2323", "proj");
$result = mysqli_query($link, "CALL get_object_event('39')");
while($row = mysqli_fetch_assoc($result)) print_r($row);
mysqli_free_result($result);
mysqli_close($link);

print_r(mysqli_error($link));

т.е. если мы закрываем соед. и открываем его заново, то получаем результат.

Выходит енто баг masqli?

спустя 17 часов [обр] Евгений[досье]
сообщение промодерировано

Я честно говоря в хранимых процедурах не очень разбираюсь, но ты все-таки попробуй писать не

while($row = mysqli_fetch_assoc($result)) print_r($row);

А так:

$result = mysql_store_result(mysql);
$row = mysql_fetch_row(result);
foreach($row as $curr)
{
    pint_r($curr);
}

Отпиши, если что-то получится, мне самому интересно

Powered by POEM™ Engine Copyright © 2002-2005