如何从内部调用存储过程获取记录集?

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 调用很可能占据了完成内部存储过程所需时间的大部分。