我有一个存储过程,在内部我想调用另一个返回记录集的过程,如何通过“ CALL”导航存储过程返回的记录集?
[edit]我一直在尝试按照建议使用TEMPORARY 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
不可以,存储过程可以生成结果集,但不能作为内部调用对其他存储过程的输出直接使用它们。从性能角度考虑,最好的办法是填充非临时工作表并使用结果。
根据您的软件和同时存在多个调用者的实际情况,您可能需要AI在某些控制表中包含带有id的auto_increment()列的会话ID概念。这样可以确保在并发的情况下,多个调用者不会踩对方的行,从而使其不可行。
AI
下面是该会议在更高层次上的工作方式。内部存储的proc将从控制表中获得一个AI值(theSession),使用它在工作表中填充一个安全分段的会话,并将其作为out参数返回给外部(调用)存储的proc。然后,该外部行可以安全地使用这些行,并在末尾(delete from workTable where sessionId=theSession)进行清理。
theSession
out
delete from workTable where sessionId=theSession
为什么我建议使用非临时工作表?需要明确的是,该工作表将是非临时的。首先,if exists drop工作变得很麻烦。不过,最重要的是,它与性能有关。临时表创建的DDL调用并不便宜。只有在进行性能测试以了解我的意思时,您才会相信这一点。这看似微不足道,但在微不足道的操作中,那些对DDL的创建调用可以很好地说明内部存储过程完成所需的大部分时间。
if exists drop