Хранимая процедура MySQL, возвращающая несколько наборов записей

Я создал несколько хранимых процедур в моей базе данных (MySQL) следующим образом.

Сохраненная процедура 1

CREATE PROCEDURE sp_Name1( param1, param2, ...... ) BEGIN ..... some code IF cond THEN call sp_Name2 //Calling 2nd procedure from here. Update SomeTable ..... SELECT '1' As Result; END IF END 

Сохраненная процедура 2

 CREATE PROCEDURE sp_Name2( param1, param2, ...... ) BEGIN ..... some code IF cond THEN SELECT '2' As Result; SELECT '3' As Result; END IF END 

Теперь я вызываю свою первую хранимую процедуру следующим образом:

 Call sp_Name1(param1, param2, ... ); 

Здесь я получаю 4 набора результатов в MySQL Workbench. 2 результатов из sp_Name2, 3rd для оператора update в sp_Name1 и 4th из оператора select, также в sp_Name1. Здесь я ищу только последний набор результатов. Иногда последовательность результатов появляется в ожидаемом порядке, что означает, что результаты могут появляться как Результат 1, Результат 2, Результат 4, Результат 3 (В этом случае я не могу судить, какой набор результатов полезен для меня, поскольку последний набор результатов может быть изменен).

Как подавить нежелательные наборы результатов?

EDIT: У меня есть прецедент для вашего лучшего понимания.

 CREATE PROCEDURE sp_LoginUser( IN Username varchar(50) , IN password varchar(50) ) BEGIN IF EXISTS( SELECT 1 FROM Users where name = UserName and Pwd = password) SET userid = 0; SET loginid = 0; SELECT userid INTO userid FROM users WHERE name = UserName and Pwd = password; IF userid > 0 THEN CALL sp_Login(userid); SET loginid = LAST_INSERT_ID(); END IF; //only this result i am expecting. IF loginid > 0 THEN SELECT userid as userid, loginid AS loginid; ELSE SELECT 0 userid, 0 loginid; END IF; END IF; END CREATE PROCEDURE sp_Login( IN Userid int ) BEGIN INSERT Logins ( userid, datetime ) VALUES ( Userid, now() ); SELECT LAST_INSERT_ID() AS loginid; END 

Итак, теперь, когда мой пользователь запрашивает логин и вводит свое имя пользователя с паролем на моей странице входа, у меня есть вызов sp_LoginUser () на моем сервере. Во многих случаях я должен вызвать sp_Login () отдельно.

В приведенном выше случае я могу установить один параметр (например, loginid) AS INOUT в процедуре sp_Login (), назначить ему LAST_INSERT_ID (), удалить инструкцию SELECT и получить в sp_LoginUser (). Но когда мне нужно вызвать sp_Login () отдельно, мне нужно объявить некоторую переменную в моей кодировке, чтобы получить значение.

Если вам не нужны эти результирующие наборы, не выбирайте их.

Когда вы выполняете выбор внутри хранимой процедуры, результат возвращается клиенту. http://dev.mysql.com/doc/refman/5.5/en/faqs-stored-procs.html#qandaitem-B-4-1-14

 CREATE PROCEDURE sp_LoginUser( IN Username varchar(50) , IN password varchar(50) ) BEGIN --put the resultset into a variable so it don't return back DECLARE doesUserExist BOOL; SELECT EXISTS( SELECT 1 FROM Users where name = UserName and Pwd = password ) INTO doesUserExist; IF doesUserExist SET userid = 0; SET loginid = 0; SELECT userid INTO userid FROM users WHERE name = UserName and Pwd = password; IF userid > 0 THEN -- call a function instead of a procedure so you don't need to call last_insert_id again SET loginid = sp_Login(userid); END IF; //only this result i am expecting. IF loginid > 0 THEN SELECT userid as userid, loginid AS loginid; ELSE SELECT 0 userid, 0 loginid; END IF; END IF; END -- this is now a function so it can return what you need CREATE FUNCTION sp_Login(Userid int) RETURNS INTEGER BEGIN INSERT Logins ( userid, datetime ) VALUES ( Userid, now() ); SET loginid = LAST_INSERT_ID(); RETURN loginid; END 

Используйте DO SELECT.. если вы не хотите возвращать набор результатов для выбора ( http://dev.mysql.com/doc/refman/5.6/en/do.html ). Тем не менее, я не понимаю, почему вы запускаете выбор в первую очередь, если вы не хотите результатов.

Почему хранимые процедуры? Вы можете сделать это с помощью обычного SQL:

 SET @previous := LAST_INSERT_ID(); INSERT INTO Logins ( userid, datetime ) SELECT Userid, now() FROM users WHERE name = UserName and Pwd = password; SELECT * FROM Logins WHERE ID = LAST_INSERT_ID() AND ID != @previous; 

Если имя пользователя / пароль верны, ваш набор строк будет содержать строку для входа – вы можете присоединиться к ней в таблице пользователя, чтобы также получить все пользовательские данные.

Если имя пользователя / пароль неверно, у вас будет пустой набор строк.

FYI, LAST_INSERT_ID() возвращает 0 если предыдущих вставок нет.


Хранимые процедуры являются наименее предпочтительным способом реализации SQL, особенно потому, что они являются наименее переносимым способом (есть и другие веские причины ); если вы можете реализовать в простом SQL, это лучший вариант. Хотя этот SQL не является полностью переносимым, его можно легко преобразовать, поскольку большинство баз данных имеют аналогичные функции и функции для mysql.