Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Несколько строк при выполнении хранимой процедуры, как? 
:(
    Опции темы
MacTep
Дата 31.1.2008, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Есть процедура: простая, для теста, чтобы понять, как это работает.

Код

DELIMITER $$

DROP PROCEDURE IF EXISTS `aliance21`.`curdemo`$$

CREATE PROCEDURE `curdemo`(out fam varchar(30))
BEGIN
  declare done int;
  declare cur1 cursor for SELECT p_fam FROM persons;
  declare cur2 cursor for SELECT count(*) FROM persons;

  OPEN cur1;
  open cur2;

  fetch cur2 into done;

  while done > 0 do
    FETCH cur1 INTO fam;
    set done = done-1;
  end while;
  
  CLOSE cur1;
  close cur2;
END$$

DELIMITER ;
Вызываю так:
Код

call curdemo(@fam);

select @fam;
Работает хорошо, но неверно. Точнее может и верно, но надо другое. Она мне выдает последнюю строку в таблице persons. А мне надо все строки из этой таблицы. Не спрашивайте, на фига тут использовать процедуру. Понимаю, что именно в этом примере - беспонтово, можно просто отделаться запросом обычным. Но... Хотелось бы научиться выводить в хранимой процедуре именно несколько строк результирующего набора данных, а не только одну. Что делаю не так?


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
MacTep
Дата 1.2.2008, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Неужели это невозможно?


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
MacTep
Дата 4.2.2008, 07:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Значит все-таки никак? smile


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
skyboy
Дата 4.2.2008, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(MacTep @  31.1.2008,  15:11 Найти цитируемый пост)
А мне надо все строки из этой таблицы

у тебя переменная объявлена так:
Цитата(MacTep @  31.1.2008,  15:11 Найти цитируемый пост)
out fam varchar(30)

одна строка длиной 30 символов. что уж тут удивительного, что процедура возвращает в этой переменной одну строку?
вот, если бы у тебя был бы объявлен тип "таблица" - вернул бы несколько строк. Но в MySQL такого типа данных пока нет.
Так что при данной постановке вопроса - никак.
PM MAIL   Вверх
MacTep
Дата 5.2.2008, 07:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Цитата

Так что при данной постановке вопроса - никак. 
А при какой постановке вопроса возможна выборка нескольких строк?


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
skyboy
Дата 5.2.2008, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



используя сериализацию в виде агрегирующей функции group_concat, можно слить кучу записей в одну строку с разделителями(аналог функции implode), но есть ньюансы: 
- используемое в качестве разделителя не может встречаться в "соединяемых" значениях - потом не отделишь одно от другого
- есть ограничение на максимальную длину подобной строки: group_concat_max_len; это ограничение можно изменить, но если пользователь имеет права на изменения переменных сервера
- необходимо парсить
---------------------------
используя динамический SQL с созданием представления(view) с проивзольным генерируемым именем, которое ты и будешь возвращать, а после обработки - прибивать. если имя представления будет достаточно уникальным(всякие там GUID() для генерации приветствуются), то коллизий не будет.
Но я не уверен, что такой подход реально реализовать: это только идея. динамический SQL точно не работает в функциях(даже если оно используется не напрямую, а из процедуры, вызываемой из функции). может и  в процедурах быть какие-то ограничения. я не в курсе :(
---------------------------
в любом случае, на твоем месте я бы попытался поставить задачу так, чтоб для её решения не использовались приёмы, нетипичные для работы с реляционными СУБД(всякие там динамические SQL и сериализация с парсингом  - это костыли)
PM MAIL   Вверх
MacTep
Дата 5.2.2008, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Цитата

на твоем месте я бы попытался поставить задачу так, чтоб для её решения не использовались приёмы, нетипичные для работы с реляционными СУБД
Ну вообще, данная задача вполне типична для реляционной БД. Зря ты так. Например, скажем, FireBird на ура выполняет такое. Просто тут дело именно в MySQL и использовать надо только его. В общем, я понял, задачу буду сводить к другому решению. Благо, обойти можно.


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
skyboy
Дата 5.2.2008, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



MacTep, в смыле? не знаю, как для FireBird, а в MSSQL имеется тип данных TABLE. Вот при помощи такого "структурного" типа данных и можно возвращать несколько записей. А вот динамически создавать View, или объединять на стороне СУБД записи в одну строку, а потом на стороне клиента парсить - вот ЭТО считаю не лучшим применением РСУБД.
я ж так и написал:
Цитата(skyboy @  5.2.2008,  09:37 Найти цитируемый пост)
всякие там динамические SQL и сериализация с парсингом  - это костыли

что, неужели под FireBird повсеместно используется "склейка" в строку с последующим парсингом?!
PM MAIL   Вверх
MacTep
Дата 6.2.2008, 07:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Цитата(skyboy @  5.2.2008,  17:03 Найти цитируемый пост)
А вот динамически создавать View, или объединять на стороне СУБД записи в одну строку, а потом на стороне клиента парсить - вот ЭТО считаю не лучшим применением РСУБД.
А я и не собираюсь это применять. ;) А в firebird просто можно при помощи suspend возвращать то, что надо в хранимой процедуре.



--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0467 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.