antklim
2.11.2009 - 11:12
Добрый день!
Возникла следующая проблема:
Есть хранимая процедура на MySQL, в которой объявлен курсор и процедура возвращает полученные строки курсора:
SQL |
delimiter | drop procedure if exists pget_info2 | create procedure pget_info2 () begin declare mheadid int; declare mhdname char(50); declare mhdstat char(1);
declare mnorows boolean; declare mnmrows int default 0;
declare ckbhead cursor for select headid, hdname, hdstat from kbhead where headid <= 10; declare continue handler for not found set mnorows = true;
open ckbhead; select found_rows() into mnmrows; the_loop: loop fetch ckbhead into mheadid, mhdname, mhdstat;
if mnorows then close ckbhead; leave the_loop; end if;
select mheadid, mhdname, mhdstat; end loop the_loop;
end |
|
В php коде хочется запросить вызов процедуры и получить весь набор данных, удовлетворяющий запросу, объявленному в курсоре.
Вот код php-скрипта:
PHP |
$conn = mysql_connect('localhost', 'хххх', 'хххх', false, 65536); mysql_select_db('хххх', $conn);
$rs = mysql_query("call pget_info2();");
while ($row = (mysql_fetch_assoc($rs))) { print_r($row); echo "<br/>"; }
echo "After fetch <br/>"; mysql_close($conn); |
Но данный код возвращает только первую запись из всего набора данных. Тот же самый результат и при использовании odbc коннектора.
С чем может быть связано такое поведение? Может для хранимых процедур необходимо использовать другие методы соединения и получения информации?
P.S. При использовании хранимой процедуры вида:
SQL |
delimiter | drop procedure if exists pget_info2 | create procedure pget_info2 () begin select headid, hdname, hdstat from kbhead where headid <= 10; end | |
php скрипт отрабатывает корректно и возвращает весь набор
данных Заранее спасибо за ответы
Спустя 1 час, 27 минут, 30 секунд (2.11.2009 - 11:39) glock18 написал(а):
antklim
выглядит просто: вы перезаписываете переменные каждый раз, выполняя fetch into.
сталкивался с такой проблемой около года назад. решение было найдено, но сначала ответьте на вопрос, чем не устраивает второй вариант процедуры?
Спустя 5 часов, 26 минут, 23 секунды (2.11.2009 - 17:06) antklim написал(а):
Второй вариант не устраивает так как необходимо проводить обработку данных внутри курсора, а затем уже выдавать обработанные записи.
Например, если у меня есть таблца с платежами и необходимо посчитать комиссию с платежа, которая зависит от набора параметров, хранящихся в других таблицах, то в одном запросе это сделать не получится.
По поводу перезаписывания переменных используя fetch into не совсем понятно, поясните пожалуйста.
Я добавлял в скрипт функцию mysql_num_rows для того чтобы определить количество полученных строк, результат работы этой функции - 1.
Спустя 1 час, 9 минут, 41 секунда (2.11.2009 - 18:15) glock18 написал(а):
Цитата |
Второй вариант не устраивает так как необходимо проводить обработку данных внутри курсора, а затем уже выдавать обработанные записи. Например, если у меня есть таблца с платежами и необходимо посчитать комиссию с платежа, которая зависит от набора параметров, хранящихся в других таблицах, то в одном запросе это сделать не получится. |
совсем не уверен, что не получится
то есть думаю, что скорее всего получится
Цитата |
По поводу перезаписывания переменных используя fetch into не совсем понятно, поясните пожалуйста. |
каждый раз вы помещаете переменные новые значения. то есть, если перевести на php, это примерно вот:
PHP |
while ($row = mysql_fetch_assoc($result)) {}
return $row; |
вернет последную строку. и результат, разумеется, только один будет.
Спустя 3 часа, 2 минуты, 24 секунды (2.11.2009 - 21:18) antklim написал(а):
То, что конструкция типа:
while ($row = mysql_fetch_assoc($result)) {}
return $row;
вернет последнюю строку это понятно. Но у меня в хранимой процедуре вывод переменных происходит на каждом шаге цикла.
И при запуске из командной строки MySQL процедура возвращает все требуемые строки курсора, а не последнюю. А при вызове из PHP возвращается только одна строка курсора - ПЕРВАЯ. Так как же все-таки получить остальные строки?
Спустя 10 минут, 30 секунд (2.11.2009 - 21:28) glock18 написал(а):
antklim
ясно, понял. невнимательно посмотрел процедуру - пхп не поддерживает (насколько я знаю, ни одна из его библиотек для работы с mysql) работу несколькими резалтсетами одновременно. А процедура каждую строку отдает именно отдельным сетом. Поэтому на выходе и получается только первая строка.
Спустя 4 минуты, 38 секунд (2.11.2009 - 21:33) antklim написал(а):
А ситуацию никак не помогут решить методы MySQLi, типа mysqli_multi_query?
Спустя 22 минуты, 11 секунд (2.11.2009 - 21:55) glock18 написал(а):
antklim
вполне, возможно, что поможет.
у pdo бывали проблемы когда надо было выбрать несколько резалтсетов. У mysqli все выглядит круто. если так же работает, то поможет ))
кстати, я до сих уверен, что проблему нужно и гораздо вернее решать одним select'ом. скажи, сколько строк на выходе получается в среднем?
Спустя 10 минут, 14 секунд (2.11.2009 - 22:05) antklim написал(а):
Одним селектом может и можно, но это будет монстр с кучей case и т.д.
На выходе может получаться от 1-й до нескольких тысяч строк. Есть еще вариант сохранить результат работы курсора во временную таблицу, а затем из нее в хп сделать селект. Но боюсь, что при одновременном обращении нескольких десятков пользователей к этой процедуре - памяти может не хватить.
Спустя 6 дней, 11 часов, 6 минут, 50 секунд (9.11.2009 - 09:12) antklim написал(а):
Тема закрыта. Решение найдено.