SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 04.04.2010 19:53:11

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Присвоить переменной результат хранимой процедуры

Ребята, привет всем.

Сбился с ног уже искать как можно присвоить переменной результат выполнения хранимой процедуры?
Например есть процедура proc:


CREATE PROCEDURE `proc`()
    SELECT 1;
END

В статье MySQL: Result set in a @variable приведен пример:

http://ondra.zizka.cz/stranky/programovani/sql/mysql_wishlist/result_set_in_variable.texy написал:

Retrieving a result set from a stored procedure

##  Retrieving a result set from a stored procedure
CALL StoredProcedure() INTO @result;

-- or

SET @result = (CALL StoredProcedure());

Оба варианта в моем случае генерируют ошибку:

mysql написал:

mysql> CALL proc() INTO @result;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @result' at line 1

mysql> SET @result = (CALL proc());
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CALL a())' at line 1

Примеч.: Интересуют собственно варианты сохранения результата не посредством фактических параметров типов OUT и INOUT.
Вот еще забавный пример:

http://www.lcard.ru/~nail/database/sybase/sql_062.html написал:

/* Процедура, возвращающая результат
при помощи оператора RETURN */

CREATE PROCEDURE Num_absent
/* Процедура определяет количество книг,
находящихся на руках у читателя, имеющего
читательскую карточку с номером Par_N_reader.
Результат возвращается посредством оператора
RETURN. */

(
IN Par_N_reader SMALLINT
)
BEGIN
    DECLARE Count_books SMALLINT;
     SELECT COUNT(*) INTO Count_books
        FROM Stepanov.Absent
        WHERE N_reader = Par_N_reader;
 RETURN Count_books;
END

При попытке создать процедуру:

mysql написал:

ERROR 1313 (42000): RETURN is only allowed in a FUNCTION

Что это? Автор статьи просто описался и имел в виду создание функции?

Отредактированно FiMko (04.04.2010 23:52:58)

Неактивен

 

#2 04.04.2010 23:38:36

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Присвоить переменной результат хранимой процедуры

Учитывая URL (конкретно, mysql_wishlist), Вы выбрали плохой источник
знаний smile

Попробуйте переписать процедуру как
CREATE PROCEDURE `proc`()
    SELECT @result := 1;
END;

Или, еще лучше, перепишите ее как функцию, они как раз для этого
предназначены.

Что касается желаний чешского разработчика, то их никогда не реализуют,
потому что они противоречат сдравому смыслу. К примеру, что нужно делать
серверу в случае
CREATE PROCEDURE blah() BEGIN SELECT 1, 2; END;;

А если так?
CREATE PROCEDURE blah() BEGIN SELECT 1; SELECT 2; END;;

Неактивен

 

#3 04.04.2010 23:47:39

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: Присвоить переменной результат хранимой процедуры

paulus написал:

Попробуйте переписать процедуру как
CREATE PROCEDURE `proc`()
    SELECT @result := 1;
END;

Ок, получается с процедурами только через "внешние" переменные.

paulus написал:

Или, еще лучше, перепишите ее как функцию, они как раз для этого
предназначены.

Собственно, я как раз и начал писать на функциях, но в процессе разработки меня зацепил MySQL Bug #36657 Can't reopen TEMPORARY table in 2 independent SELECTs in a FUNCTION.

Valeriy Kravchuk написал:

"You cannot refer to a TEMPORARY table more than once in the same query."

But it is not clear if entire stored function/procedure should be treated as "same
query". If current behaviour is intended (I think so) then manual page quoted above
should be clarified, with additional example like this.

Однако в комментариях к проблеме указано, что

Ondra Zizka написал:

Note that it works well for a PROCEDURE. Procedure call is not treated as "same query"?

Поэтому я решил попробовать переделать на процедуры...

Отредактированно FiMko (04.04.2010 23:48:39)

Неактивен

 

#4 04.04.2010 23:55:54

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Присвоить переменной результат хранимой процедуры

Процедура — это атомарный кусок вида «сделай то-то». Он не возвращает
результата. Бага — неприятная штука. А без алиасов переписать функцию
не удается?

Неактивен

 

#5 05.04.2010 00:03:28

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: Присвоить переменной результат хранимой процедуры

paulus написал:

А без алиасов переписать функцию
не удается?

Ну у меня не совсем в алиасах проявилась проблема, но суть была несколько схожей. Некая функция func0 последовательно вызывает функции func1 и func2, каждая из которых создает временную таблицу 'temp' для своих нужд, так вот при запуске функции func0 получаю ошибку "ERROR 1137 (HY000): Can't reopen table 'temp'". Если тело функций func1 и func2 непосредственно поместить в функцию func0, всё работает.

Отредактированно FiMko (05.04.2010 00:05:25)

Неактивен

 

#6 05.04.2010 00:07:20

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Присвоить переменной результат хранимой процедуры

... каждая из которых создает временную таблицу ...

А она потом за собой удаляет?

Неактивен

 

#7 05.04.2010 00:18:19

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: Присвоить переменной результат хранимой процедуры

LazY написал:

... каждая из которых создает временную таблицу ...

А она потом за собой удаляет?

Интересно... а ведь похоже помогло. Нигде не нашел такого условия, о том, что нужно удалять таблицу. Спасибо!
В любом случае узнал походя о присвоении результатов хранимых процедур smile

Кстати, функции у меня к тому же начинаются со слов:

DROP TEMPORARY TABLE IF EXISTS temp;
CREATE TEMPORARY TABLE temp (
    word VARCHAR(100) PRIMARY KEY
) ENGINE=MEMORY;

Но вот добавление DROP также в конце функции помогло. Действительно помогает, дважды перепроверил...

Отредактированно FiMko (05.04.2010 00:30:35)

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson