我正在尝试在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
虽然在我看来这甚至有些朦胧。
作为参考,虽然我认为它不一定相关,但初始查询将连接四个表以形成分层权限的模型,然后根据特定权限的链的高度,它将检索有关应该继承该权限的子女的其他信息。
答案 0 :(得分:69)
这样的事情应该可以解决问题(但是,请在片段之后阅读以获取更多信息)
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
需要考虑的一些事项......
关于上面的代码段:
更一般地说:试图避免需要光标。
我故意命名游标变量curs [e],因为游标是混合的祝福。它们可以帮助我们实现复杂的业务规则,这些规则可能难以用SQL的声明形式表达,但它然后使我们使用SQL的过程(命令式)形式,这是SQL的一般特性,它既不是非常友好/具有表现力,编程方面,而且往往效率低下。
也许您可以考虑在“普通”(声明性)SQL查询的上下文中表达所需的转换和过滤。
答案 1 :(得分:4)
使用游标。
在阅读文档时,可以将光标视为缓冲读取器。如果您将每一行视为文档中的一行,那么您将阅读下一行,执行操作,然后前进光标。