如何从内部调用存储过程获取记录集?
How to get recordset from internal call to stored procedure?
我有一个存储过程,我想在内部调用另一个过程 returns 记录集,如何通过 'CALL' 导航存储过程返回的记录集?
[edit] 我一直在尝试按照建议使用临时 TABLE,但遇到问题:
DROP TEMPORARY TABLE IF EXISTS tbl_HeadOfDepts;
CREATE TEMPORARY TABLE tbl_HeadOfDepts (biDept_id tinyint(4))
INSERT INTO tbl_HeadOfDepts CALL rsHeadOfAnyDepartments(vcCompKey, biWho_id);
我需要使用 CALL,因为 'rsHeadOfAnyDepartments' 不是一个函数,但这不会被接受。
工作正在进行中,但我目前所拥有的尚未被编辑接受:
BEGIN
#--
# Procedure:
# rsWhoCanIaccess
#
# Parameters:
# vcCompKey, the key corresponding to the company
# biWho_id, the id of the person to check access for
#
# Returns:
# recordset containing all the people this person can access
#--
DECLARE tiSuperUser tinyint(4);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE,
@errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
CALL procLogError(vcCompKey, CONCAT("rsWhoCanIaccess: "
,@errno, " (", @sqlstate, "): ", @text));
END;
#Is this user a super user?
SELECT tiIsSuperUser(vcCompKey, biWho_id) INTO tiSuperUser;
SET tiSuperUser = 0;#Hack for testing
IF (tiSuperUser = 1) THEN
#The user is a superuser, return everyone in the company
SELECT
t1.biPerson_id
FROM
tbl_people t1
INNER JOIN
tbl_companies t2
ON
t1.biCompany_id=t2.biCompany_id
AND
t2.vcKey=vcCompKey;
ELSE
#User is not a superuser, is the user head of any departments?
DROP TEMPORARY TABLE IF EXISTS tbl_HeadOfDepts;
CREATE TEMPORARY TABLE tbl_HeadOfDepts (biDept_id tinyint(4))
INSERT INTO tbl_HeadOfDepts CALL rsHeadOfAnyDepartments(vcCompKey, biWho_id);
SELECT * FROM tbl_HeadOfDepts;
END IF;
END
internally I want to call another procedure that returns a record set,
在你的内部程序中创建一个 TEMPORARY TABLE
并填充那个临时 table 说 insert into your_temp_table select query
。那么您可以在任何地方的外部查询中使用相同的温度table。
它甚至可以是正常的 table,不需要是临时的 table。还要确保在您的程序计算完成后 DROP
table 作为清理。
根据您的评论,这是错误的。你应该像下面那样做(示例代码)
create procedure rsHeadOfAnyDepartments(vcCompKey varchar(10), biWho_id int)
as
begin
DROP TEMPORARY TABLE IF EXISTS tbl_HeadOfDepts;
CREATE TEMPORARY TABLE tbl_HeadOfDepts(col1 int, col2 varchar(10), col3 varchar(30));
INSERT INTO tbl_HeadOfDepts
SELECT col1, col2, col3
FROM tblTest;
end
不,存储过程可以生成结果集,但不能直接使用它们作为对其他存储过程的内部调用的输出。你能做的最好的 performance-wise 就是填充 non-temporary 工作 table 并使用结果。
根据您的软件和多个调用者并发的实际情况,您可能需要在某些控件中包含一个带有 auto_increment (AI
) 列的 session id 概念 table。这将确保在并发情况下,多个调用者不会踩到彼此的行,从而使其成为 non-viable.
session 的工作原理如下。内部存储过程将从控件 table 传递一个 AI
值 (theSession
),使用它来填充工作 table 中的安全分段 session ,并且 return 作为外部(调用)存储过程的 out
参数。那个外面的可以安全地使用这些行,并在最后清理 (delete from workTable where sessionId=theSession
)。
为什么我建议 non-temporary 作品 table?明确地说,工作 table 将是 non-temporary。首先是让 if exists drop
工作的麻烦。不过,最重要的是,它与性能有关。临时 table 创建的 DDL 调用并不便宜。只有当您进行性能测试以了解我的意思时,您才会相信这一点。这可能看起来微不足道,但在微不足道的操作中,那些用于创建的 DDL 调用很可能占据了完成内部存储过程所需时间的大部分。
我有一个存储过程,我想在内部调用另一个过程 returns 记录集,如何通过 'CALL' 导航存储过程返回的记录集?
[edit] 我一直在尝试按照建议使用临时 TABLE,但遇到问题:
DROP TEMPORARY TABLE IF EXISTS tbl_HeadOfDepts;
CREATE TEMPORARY TABLE tbl_HeadOfDepts (biDept_id tinyint(4))
INSERT INTO tbl_HeadOfDepts CALL rsHeadOfAnyDepartments(vcCompKey, biWho_id);
我需要使用 CALL,因为 'rsHeadOfAnyDepartments' 不是一个函数,但这不会被接受。
工作正在进行中,但我目前所拥有的尚未被编辑接受:
BEGIN
#--
# Procedure:
# rsWhoCanIaccess
#
# Parameters:
# vcCompKey, the key corresponding to the company
# biWho_id, the id of the person to check access for
#
# Returns:
# recordset containing all the people this person can access
#--
DECLARE tiSuperUser tinyint(4);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE,
@errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
CALL procLogError(vcCompKey, CONCAT("rsWhoCanIaccess: "
,@errno, " (", @sqlstate, "): ", @text));
END;
#Is this user a super user?
SELECT tiIsSuperUser(vcCompKey, biWho_id) INTO tiSuperUser;
SET tiSuperUser = 0;#Hack for testing
IF (tiSuperUser = 1) THEN
#The user is a superuser, return everyone in the company
SELECT
t1.biPerson_id
FROM
tbl_people t1
INNER JOIN
tbl_companies t2
ON
t1.biCompany_id=t2.biCompany_id
AND
t2.vcKey=vcCompKey;
ELSE
#User is not a superuser, is the user head of any departments?
DROP TEMPORARY TABLE IF EXISTS tbl_HeadOfDepts;
CREATE TEMPORARY TABLE tbl_HeadOfDepts (biDept_id tinyint(4))
INSERT INTO tbl_HeadOfDepts CALL rsHeadOfAnyDepartments(vcCompKey, biWho_id);
SELECT * FROM tbl_HeadOfDepts;
END IF;
END
internally I want to call another procedure that returns a record set,
在你的内部程序中创建一个 TEMPORARY TABLE
并填充那个临时 table 说 insert into your_temp_table select query
。那么您可以在任何地方的外部查询中使用相同的温度table。
它甚至可以是正常的 table,不需要是临时的 table。还要确保在您的程序计算完成后 DROP
table 作为清理。
根据您的评论,这是错误的。你应该像下面那样做(示例代码)
create procedure rsHeadOfAnyDepartments(vcCompKey varchar(10), biWho_id int)
as
begin
DROP TEMPORARY TABLE IF EXISTS tbl_HeadOfDepts;
CREATE TEMPORARY TABLE tbl_HeadOfDepts(col1 int, col2 varchar(10), col3 varchar(30));
INSERT INTO tbl_HeadOfDepts
SELECT col1, col2, col3
FROM tblTest;
end
不,存储过程可以生成结果集,但不能直接使用它们作为对其他存储过程的内部调用的输出。你能做的最好的 performance-wise 就是填充 non-temporary 工作 table 并使用结果。
根据您的软件和多个调用者并发的实际情况,您可能需要在某些控件中包含一个带有 auto_increment (AI
) 列的 session id 概念 table。这将确保在并发情况下,多个调用者不会踩到彼此的行,从而使其成为 non-viable.
session 的工作原理如下。内部存储过程将从控件 table 传递一个 AI
值 (theSession
),使用它来填充工作 table 中的安全分段 session ,并且 return 作为外部(调用)存储过程的 out
参数。那个外面的可以安全地使用这些行,并在最后清理 (delete from workTable where sessionId=theSession
)。
为什么我建议 non-temporary 作品 table?明确地说,工作 table 将是 non-temporary。首先是让 if exists drop
工作的麻烦。不过,最重要的是,它与性能有关。临时 table 创建的 DDL 调用并不便宜。只有当您进行性能测试以了解我的意思时,您才会相信这一点。这可能看起来微不足道,但在微不足道的操作中,那些用于创建的 DDL 调用很可能占据了完成内部存储过程所需时间的大部分。