在MySQL中循环遍历结果集

我正在尝试在MySQL中编写一个存储过程,它将执行一个稍微简单的select查询,然后遍历结果以决定是执行其他查询,数据转换还是完全丢弃数据。 实际上,我想要实现这个:

$result = mysql_query("SELECT something FROM somewhere WHERE some stuff"); while ($row = mysql_fetch_assoc($result)) { // check values of certain fields, decide to perform more queries, or not // tack it all into the returning result set } 

只有,我只需要在MySQL中,所以它可以被称为一个过程。 我知道对于触发器,有FOR EACH ROW ...语法,但是我找不到在CREATE TRIGGER ...语法之外使用的任何东西。 我已经阅读了MySQL中的一些循环机制,但到目前为止,我可以想象的是,我将实现这样的事情:

 SET @S = 1; LOOP SELECT * FROM somewhere WHERE some_conditions LIMIT @S, 1 -- IF NO RESULTS THEN LEAVE -- DO SOMETHING SET @S = @S + 1; END LOOP 

虽然这在我看来有点朦胧。

作为参考,虽然我不认为这是必要的,但最初的查询将连接在一起形成一个分层权限的模型,然后基于链的特定权限是多高,它将检索有关应该inheritance该权限的子女。

像这样的事情应该做的伎俩(然而,阅读更多的信息片段后)

 CREATE PROCEDURE GetFilteredData() BEGIN DECLARE bDone INT; DECLARE var1 CHAR(16); -- or approriate type DECLARE Var2 INT; DECLARE Var3 VARCHAR(50); DECLARE curs CURSOR FOR SELECT something FROM somewhere WHERE some stuff; DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1; DROP TEMPORARY TABLE IF EXISTS tblResults; CREATE TEMPORARY TABLE IF NOT EXISTS tblResults ( --Fld1 type, --Fld2 type, --... ); OPEN curs; SET bDone = 0; REPEAT FETCH curs INTO var1,, b; IF whatever_filtering_desired -- here for whatever_transformation_may_be_desired INSERT INTO tblResults VALUES (var1, var2, var3 ...); END IF; UNTIL bDone END REPEAT; CLOSE curs; SELECT * FROM tblResults; END 

有几件事要考虑…

关于上面的代码片段:

  • 可能希望将部分查询传递给存储过程,可能特别是search条件,使其更通用。
  • 如果这个方法被多个会话调用等,可能想要传递一个会话ID的sorting来创build一个唯一的临时表名称(实际上是不必要的担心,因为不同的会话不共享相同的临时文件名称空间;请参阅Gruber的评论,下面)
  • 一些部分,如variables声明,SELECT查询等需要适当的指定

更一般地说: 试图避免需要一个游标

我故意将游标variables命名为curs [e],因为游标是一种混合的祝福。 它们可以帮助我们实现复杂的业务规则,这些规则在SQL的声明式forms中可能很难expression出来,但是它使我们能够使用SQL的过程式(命令式)forms,这是SQL的一个通用特性,它既不是非常友好/performance力,编程方式,而且往往效率不高。

也许你可以研究expression在“简单”(声明式)SQL查询语境中所需的转换和过滤。

使用游标。

阅读文档时,可以将光标看作缓冲读取器。 如果您将每行视为文档中的一行,那么您将读取下一行,执行操作,然后移动光标。