gpt4 book ai didi

mysql - MySQL准备语句-如何循环通过

转载 作者:行者123 更新时间:2023-11-29 05:21:01 27 4
gpt4 key购买 nike

我有一个包含ID号的表,我需要遍历它,并在准备好的语句中用作变量。我不知道是否需要为此使用存储过程,或者是否可以使用常规查询。这里有一个简单的例子。

SELECT id from var_list;

loop through @ID = var_list.id ....


SET @s1 = "SELECT * FROM data WHERE id = @ID";
PREPARE stmt1 FROM @s1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;

如注释中所述,我只需要这个来导出一些数据,我在表中有大约50-100个ID,并编写了一个查询,以便一次将一个文件导出到服务器。
编辑
我计划将每次迭代的结果转储到一个文件中,使用类似于。。。。
INTO OUTFILE '/tmp/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'

最佳答案

正如其他人已经建议的那样,我们通常避免通过resultset RBAR(一行接一行地折磨行)循环,这主要是出于性能原因。我们只是不想养成遍历结果集的习惯。但这并不能回答你提出的问题。
为了回答您提出的问题,这里有一个MySQL存储程序的基本示例,该程序使用游标分别处理查询返回的行。MySQL不支持匿名块,所以唯一的方法是在MySQL存储程序中,比如

DELIMITER $$

CREATE PROCEDURE loop_through_var_list
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE v_id INT DEFAULT NULL;
DECLARE csr_var_list CURSOR FOR SELECT id FROM var_list ORDER BY id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN csr_var_list;
get_id: LOOP
FETCH csr_var_list INTO v_id;
IF done = 1 THEN
LEAVE get_id;
END IF;

-- at this point, we have an id value in v_id, so we can do whatever
SET @s1 = CONCAT('SELECT ... WHERE id =''', v_id, ''' ...');


END LOOP get_id;
CLOSE csr_var_list;
END$$

DELIMITER ;

执行程序:
CALL loop_through_var_list();

注意:MySQL中处理游标的语法与其他数据库有很大不同。
为了得到“循环”,我们需要使用 LOOP ... END LOOP构造。
但是为了防止循环永远运行,我们需要一个允许我们退出循环的休假语句。
我们使用条件测试来确定何时离开。在这个例子中,我们希望在处理完最后一行之后退出。
当没有更多的行要提取时, FETCH将引发异常。
我们在一个CONTINUE处理程序中“捕获”那个异常(出于某种神秘的原因,“处理程序”必须是最后声明的东西;如果我们试图在一个处理程序(而不是另一个处理程序)之后声明某个东西,MySQL会抛出一个错误)
当MySQL抛出“不再有行”异常时,将触发处理程序代码。在本例中,我们只是将一个变量(名为 done)设置为一个值。
由于它是一个“continue”处理程序,处理从引发异常的语句开始备份,在本例中,该语句将是获取之后的语句。所以,我们要做的第一件事就是检查我们是否“完成”了。如果我们“完成”,那么我们退出循环,关闭光标。
否则,我们知道存储在名为 id的过程变量中的 var_list值。所以现在我们可以随心所欲了。看起来你想把一些SQL文本放到一个用户定义的变量中(包括VyID的值到SQL文本中,然后准备、执行和释放准备)。
请确保用与 v_idv_id列的数据类型匹配的适当数据类型声明 id变量,我只是假设它是一个INT。
当我们到达循环的末尾时,MySQL“循环”回到循环的开头,然后我们再次离开。
在循环的主体中,可能需要将v_id CONCAT到要执行的SQL文本中。看来你已经准备好了,处理准备好了。对于测试,您可能需要在游标声明中的SELECT上添加一个LIMIT子句,然后在正文中执行一个简单的SELECT v_id;,在添加更多代码之前验证循环是否有效。
后续行动
我想提及另一种任务的替代方法,即运行基于模板的一系列语句,替换单个SQL select语句提供的值。。。
例如,如果我有这个模板:
SELECT * 
INTO OUTFILE '/tmp/orders_@ID.csv'
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM data
WHERE id = @ID
ORDER BY 1

我需要用SELECT语句返回的列表中的特定ID值替换@ID的出现,例如。
SELECT id
FROM var_list
WHERE id IS NOT NULL
GROUP BY id

我可能不会使用带有游标循环的MySQL存储程序,而是使用不同的方法。
我将使用SELECT语句生成一组可以执行的SQL语句。假设 var_list是整数类型,我可能会这样做:
SELECT CONCAT(' SELECT * 
INTO OUTFILE ''/tmp/orders_',s.id,'.csv''
FIELDS TERMINATED BY '','' ENCLOSED BY ''"''
LINES TERMINATED BY ''\n''
FROM data
WHERE id = ',s.id,'
ORDER BY 1;') AS `stmt`
FROM ( SELECT v.id
FROM var_list v
WHERE v.id IS NOT NULL
GROUP BY v.id
) s
ORDER BY s.id

对于从 id返回的 id的每个值,该语句返回可以(并且需要)执行的SQL SELECT语句的文本。把它捕获到一个文本文件中会给我一个可以运行的SQL脚本。

关于mysql - MySQL准备语句-如何循环通过,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25778922/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com