UmbrellaCoders
@UmbrellaCoders
PHP, JS Developer

MySQL, Хранимые процедуры и функции, как вернуть multiple rows?

Приветствую! До этого момента кроме кроме запросов из "бэкенда" не использовал SQL, но сейчас решил взяться за вопрос и сразу залип на хранимых процедурах и функциях.

Собственно, есть таблица на 100к записей, я хочу получить все уникальные wm_id, пишу следующий код

CREATE PROCEDURE get_wm_ids(OUT wm_ids JSON)

	 SET wm_ids = (SELECT wm_id AS json
	 FROM visitors
         WHERE wm_id REGEXP '^[[:digit:]]+$'
	 OR wm_id = ""
	 GROUP BY wm_id);


Вызываю, где-то

CALL get_wm_ids(@wm_ids);

И получаю
CALL get_wm_ids(@wm_ids) Error Code: 1242. Subquery returns more than 1 row

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

Если делать так

CREATE PROCEDURE get_wm_ids()

	 SELECT wm_id AS json
	 FROM visitors
         WHERE wm_id REGEXP '^[[:digit:]]+$'
	 OR wm_id = ""
	 GROUP BY wm_id;
       

CALL get_wm_ids();

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

p.s. Строго плиз не судите, изучаю это дело только один день.
  • Вопрос задан
  • 1929 просмотров
Решения вопроса 2
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Если в процедуре нужно построчно обходить результат выборки, то придётся использовать курсор
СREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR(16);
  DECLARE b INT;

  DECLARE cur CURSOR FOR SELECT id, data FROM t1;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur;
  read_loop: LOOP
    FETCH cur INTO a, b;
    IF done THEN
      LEAVE read_loop;
    END IF;
    здесь выполняются нужные действия
  END LOOP;

  CLOSE cur;
END
Ответ написан
@d-stream
Готовые решения - не подаю, но...
Процедура может возвращать результат селекта. Я бы даже сказал чаще всего так и бывает. А вот возвращающие что-то одно (функции) - пореже.

Как типичный вариант - на входе получает кучку параметров-фильтров, флагов, а на выходе вываливает селект с отбором, сортировкой, группировкой по этим флагам.

Как тупой образчик отбор контактов:

create procedure get_contacts (idescr char, itype int, show_hidden bit )
begin
... делаем кучи каких-нибудь проверок
и где-то в конце

select ... from ... join ....
where contacts.descr like idescr
and (itype=0 or contacts.type=itype)
and (show_hidden=1 or contacts.is_hidden=0)
end

вызвав процедуру с параметрами '%%', 0, 1 - получим всех контрагентов, '%%', 0, 0 - только тех у кого не взведен флаг "скрытый" и т.п.

естественно пример примитивный и не учитывает кучи всего - сам принцип.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы