我在我的数据库(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, ... );
这里我在MySQL Workbench中获得了4个结果集。 sp_Name2中的2个结果,sp_Name1中的update语句的第3个结果和select语句中的第4个结果,也是sp_Name1中的结果。在这里,我只是寻找最后的结果集。有时候结果序列会出现在预期的顺序中,这意味着结果可能会出现在结果1,结果2,结果4,结果3中(在这种情况下,我无法判断哪个结果集对我有用,因为最后的结果集可能被改变了)。
如何抑制不需要的结果集?
编辑: 我有一个用例,以便您更好地理解。
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()。
在上面的例子中,我可以在sp_Login()过程中设置一个参数(例如,loginid)AS INOUT,为其分配LAST_INSERT_ID(),删除SELECT语句并在sp_LoginUser()中检索。 但是当我需要单独调用sp_Login()时,我必须在编码中声明一些变量来检索值。
答案 0 :(得分:6)
如果您不想要这些结果集,请不要选择它们。
答案 1 :(得分:2)
在存储过程中执行select时,结果集将返回给客户端。 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
答案 2 :(得分:2)
如果您不想为选择(http://dev.mysql.com/doc/refman/5.6/en/do.html)返回结果集,请使用DO SELECT..
。但是,如果您不想要结果,我不明白为什么您首先运行选择。
答案 3 :(得分:1)
我不确定您为什么在sp_Login中选择LAST_INSERT_ID()并再次在sp_LoginUser中选择?
如果需要从sp_Login返回LAST_INSERT_ID(),则需要为其分配输出变量或考虑使用标量函数。
答案 4 :(得分:1)
为什么存储过程?您可以使用普通的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;
如果用户名/密码正确,您的行集将包含登录行 - 您可以将其加入用户表以获取所有用户数据。
如果用户名/密码不正确,您将拥有一个空的行集。
仅供参考,LAST_INSERT_ID()
如果之前没有插入,则返回0
。
存储过程是实现SQL的最少首选方式,特别是因为它们是可移植方式最少(也有other good reasons);如果你可以在普通的SQL中实现它是一个更好的选择。虽然这个SQL不是完全可移植的,但它可以很容易地转换,因为大多数数据库都具有与mysql类似的功能和特性。
答案 5 :(得分:0)
返回多个值,例如
CREATE PROCEDURE `sp_ReturnValue`(
p_Id int(11), -- Input param
OUT r_status1 INT(11) -- output param
OUT r_status2 VARCHAR(11) -- output param
OUT r_status3 INT(11) -- output param
)
BEGIN
SELECT Status FROM tblUsers WHERE tblUsers_ID = p_Id; // use of input param
SET r_status1 = 2; // use of output param
SET r_status2 = "ABCD"; // use of string output param
SET r_status3 = 2; // use of output param
END
和READ
CREATE PROCEDURE `sp_ReadReturnValue`()
BEGIN
SELECT @ret_value1 AS ret_value1,
@ret_value2 AS ret_value2,
@ret_value3 AS ret_value3;
END
Out参数的节点内参数
con.query("CALL sp_ReturnValue(?, @ret_value1, @ret_value2, @ret_value3); CALL sp_ReadReturnValue;", [id], (err, rows) => {
console.log("Print return value \n ");
console.log(rows[1][0].ret_value1 "\n");
console.log(rows[1][0].ret_value2 "\n");
console.log(rows[1][0].ret_value3 );
})