当前位置: 首页 > 面试题库 >

在MySQL中循环结果集

严宇
2023-03-14
问题内容

我正在尝试在MySQL中编写一个存储过程,该存储过程将执行一个稍微简单的选择查询,然后循环遍历结果,以便决定是执行其他查询,数据转换还是完全丢弃数据。有效地,我想实现这一点:

$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

尽管这在我心中还是有些朦胧的。

作为参考,尽管我认为这不一定必要,但初始查询将把四个表连接在一起,形成一个层次权限模型,然后根据特定权限在链的最高位置,将检索有关应该继承该权限的子级。


问题答案:

这样的事情应该可以解决问题(但是,请在摘要后阅读以获取更多信息)

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

需要考虑的几件事…

关于以上代码段:

  • 可能希望将查询的一部分传递给存储过程,尤其是搜索条件,以使其更加通用。
  • 如果要由多个会话等调用此方法,则可能希望传递一个会话ID来创建唯一的临时表名(实际上是不必要的考虑,因为不同的会话不共享相同的临时文件名称空间;请参阅下面Gruber的评论) )
  • 需要正确指定一些部分,例如变量声明,SELECT查询等。

更一般而言: 尝试避免需要游标

我特意将游标变量命名为curs
[e],因为游标是一种混杂的祝福。它们可以帮助我们实施复杂的业务规则,而这些业务规则可能很难以SQL的声明形式来表达,但是它带给我们使用SQL的过程式(命令式)形式,这是SQL的一般功能,既不是非常友好/表现力,编程方面以及效率通常较低的方面。

也许您可以研究在“普通”(说明性)SQL查询的上下文中表达所需的转换和过滤。



 类似资料:
  • 在下面的代码: 在上面的代码中,我从用户那里得到一个表名列表,然后在for循环中对它们进行迭代。代码正在工作,但它没有将数据插入临时表并以错误结束。 错误: 请帮我找出为什么会出现这个错误?

  • 我正在尝试对从刀片模板中的控制器中的查询返回的数据数组运行foreach循环。无论我如何尝试,我总是会收到一个错误,说“Undefined offset:1”。如果我只是简单地打印出,它会显示我所期望的,但由于某种原因,它没有foreach循环。 下面是我从日志中的查询中得到的一个打印输出(实际数组显然有更多的值): 我一直在尝试不同的方法,因为这是我最终要实现的目标: 我希望这是一件简单的事情,

  • 这个问题应该很简单,而且可能会让人恼火,但我仍然对使用Java关闭结果集感到怀疑。每个语句都应该这样做,或者结果集应该只在final中关闭?

  • 这是我在控制器中的getIndex()函数中的东西 所以我希望从循环中获取所有类别名称。 但是,例如,如果我希望通过在视图中执行此操作来获得结果 结果是 > 对象(类别)169(20){[“可填充”:受保护]= 字符串(3)“foo1” 第一个结果从哪里来,我如何摆脱它?谢谢!

  • 问题内容: 我正在尝试从MYSQL下载图像(.png)文件。有时它工作正常。无法找到确切的问题。它可以在Jboss服务器上正常工作。尝试在Apche上的本地计算机中运行时引发错误。 请帮助我修复错误。这是我的Java代码。 这是堆栈跟踪输出: 问题答案: 您打了两次电话。我假设您的查询仅返回1行,因为您尝试通过进行匹配。当第二个被调用时,中没有要返回的行。这就是抛出an的原因。像这样删除第一个:

  • 我有一个用户表和一个高尔夫比赛分数表。当用户参加比赛时,他使用表格在结果表中记录分数。我想显示一个结果表,显示用户的完整列表和比赛的分数。表中有八列分数——每门课一列。我正在努力使用php代码来显示结果分数。如果一名球员已经比赛,他的得分将正确显示,但如果表中的下一名球员没有比赛,则他的得分将显示为表中高于他的球员的得分。这将在列表中继续下去,直到获得真正的分数。我试图找到答案,但没有成功。这是我