在 MySQL 中循环结果集
我正在尝试在 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
尽管这在我的脑海中有些模糊。
作为参考,虽然我认为这不一定相关,但初始查询将把四个表连接在一起以形成层次结构权限模型,然后根据特定权限在链上的高度,它将检索有关的附加信息应继承该许可的子女。
I am trying to write a stored procedure in MySQL which will perform a somewhat simple select query, and then loop over the results in order to decide whether to perform additional queries, data transformations, or discard the data altogether. Effectively, I want to implement this:
$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
}
Only, I want it only in MySQL, so it can be called as a procedure. I know that for triggers, there is the FOR EACH ROW ...
syntax, but I can't find mention of anything like this for use outside of the CREATE TRIGGER ...
syntax. I have read through some of the looping mechanisms in MySQL, but so far all I can imagine is that I would be implementing something like this:
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
Although even this is somewhat hazy in my mind.
For reference, though I don't think it's necessarily relevant, the initial query will be joining four tables together to form a model of hierarchal permissions, and then based on how high up the chain a specific permission is, it will retrieve additional information about the children to which that permission should be inherited.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
像这样的事情应该可以解决问题(但是,请阅读代码片段以获取更多信息)
需要考虑的一些事情...
关于上面的代码片段:
更一般地说:尝试避免需要游标。
我特意将游标变量命名为 curs[e],因为游标是喜忧参半的。它们可以帮助我们实现复杂的业务规则,这些规则可能很难用 SQL 的声明式形式来表达,但它随后让我们使用 SQL 的过程式(命令式)形式,这是 SQL 的一个普遍特征,但它既不是很友好/富有表现力、编程方面,但性能方面往往效率较低。
也许您可以考虑在“普通”(声明性)SQL 查询的上下文中表达所需的转换和过滤。
Something like this should do the trick (However, read after the snippet for more info)
A few things to consider...
Concerning the snippet above:
More generally: trying to avoid needing a cursor.
I purposely named the cursor variable curs[e], because cursors are a mixed blessing. They can help us implement complicated business rules that may be difficult to express in the declarative form of SQL, but it then brings us to use the procedural (imperative) form of SQL, which is a general feature of SQL which is neither very friendly/expressive, programming-wise, and often less efficient performance-wise.
Maybe you can look into expressing the transformation and filtering desired in the context of a "plain" (declarative) SQL query.
使用光标。
在阅读文档时,可以将光标视为缓冲阅读器。如果您将每一行视为文档中的一行,那么您将读取下一行,执行操作,然后前进光标。
Use cursors.
A cursor can be thought of like a buffered reader, when reading through a document. If you think of each row as a line in a document, then you would read the next line, perform your operations, and then advance the cursor.
在存储过程中使用游标。
准备 SQL 查询
创建游标,用于保存 SQL 查询返回的结果集。
要在从游标获取行时不返回任何结果时安全退出,请声明一个名为 NOT FOUND 的处理程序,并将值设置为已声明的变量。
在从游标获取下一行之前打开游标。
获取光标指向的下一行,然后将光标移动到下一行。
根据所需的用例运行所需的业务逻辑。
执行上面的脚本,你会发现创建了一个新的存储过程。
通过输入将接收奖金金额的部门 ID 来调用或调用存储过程。
希望这能解释“如何使用存储过程中使用的游标进行迭代”
Using a cursor within a stored procedure.
Prepare the SQL Query
Create the cursor which will hold the result set returned by the SQL Query.
To have a safe exit when fetching a row from cursor does not return any result then declare a handler called NOT FOUND and set value to a declared variable
Open the Cursor before you can fetch the next row from the cursor.
Fetch the next row pointed by the cursor and move the cursor to next row after that.
Run the desired business logic according to the usecase required.
Execute the above script and you will find a new Stored Procedure created.
Call or Invoke the Stored Procedure by inputing the departmentId which will receive the bonus amount.
Hope this explains "How to iterate using Cursors used within Stored Procedure"