首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何遍历一个表的所有行?(MySQL)

如何遍历一个表的所有行?(MySQL)
EN

Stack Overflow用户
提问于 2011-04-28 18:48:20
回答 5查看 312.3K关注 0票数 104

我有一个表A,并且有一个主键ID。

现在我要遍历A中的所有行。

我找到了类似于'for each record in A‘的内容,但在MySQL中似乎不是这样做的。

对于每一行,我想要获取一个字段并对其进行转换,将其插入到另一个表中,然后更新该行的一些字段。我可以将select部分和insert放入一条语句中,但我不知道如何将更新也放入其中。所以我想要循环。在实践中,除了MySQL,我不想使用其他任何东西。

编辑

如果能举个例子,我会很感激。

以及一种不需要放入程序中的解决方案。

编辑2个

好的,想一想这个场景:

表A和B,每个都有字段ID和VAL。

现在这是我想要做的伪代码:

for(each row in A as rowA)
{
  insert into B(ID, VAL) values(rowA[ID], rowA[VAL]);
}

基本上是使用循环将A的内容复制到B中。

(这只是一个简化的示例,当然您不会为此使用循环。)

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-05-03 10:30:17

因为循环的建议暗示了对过程类型解决方案的请求。这是我的。

从表中获取的任何单个记录上的任何查询都可以包装在一个过程中,使其遍历表的每一行,如下所示:

首先删除任何具有相同名称的现有过程,并更改分隔符,这样SQL就不会在编写过程时尝试运行每一行。

DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;

下面是示例中的过程(为了清楚起见,使用了table_A和table_B )

CREATE PROCEDURE ROWPERROW()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
SELECT COUNT(*) FROM table_A INTO n;
SET i=0;
WHILE i<n DO 
  INSERT INTO table_B(ID, VAL) SELECT (ID, VAL) FROM table_A LIMIT i,1;
  SET i = i + 1;
END WHILE;
End;
;;

然后别忘了重置分隔符

DELIMITER ;

并运行新的过程

CALL ROWPERROW();

您可以在"INSERT INTO“行做任何您想做的事情,我只是从您的示例请求中复制了这一行。

请注意,这里使用的"INSERT INTO“行反映了问题中的行。根据对此答案的注释,您需要确保您的查询在语法上是正确的,无论您运行的是哪种版本的SQL。

在简单的情况下,您的ID字段是递增的,并且从1开始,示例中的行可以变成:

INSERT INTO table_B(ID, VAL) VALUES(ID, VAL) FROM table_A WHERE ID=i;

将"SELECT COUNT“行替换为

SET n=10;

将允许您仅在table_A中的前10条记录上测试查询。

最后一件事。这个过程也很容易跨不同的表嵌套,这也是我可以在一个表上执行一个过程的唯一方法,该过程从父表的每一行动态地将不同数量的记录插入到新表中。

如果你需要它运行得更快,那么一定要试着让它基于set,如果不是这样,那么这是很好的。你也可以用游标的形式重写上面的代码,但这可能不会提高性能。例如:

DROP PROCEDURE IF EXISTS cursor_ROWPERROW;
DELIMITER ;;

CREATE PROCEDURE cursor_ROWPERROW()
BEGIN
  DECLARE cursor_ID INT;
  DECLARE cursor_VAL VARCHAR;
  DECLARE done INT DEFAULT FALSE;
  DECLARE cursor_i CURSOR FOR SELECT ID,VAL FROM table_A;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
  OPEN cursor_i;
  read_loop: LOOP
    FETCH cursor_i INTO cursor_ID, cursor_VAL;
    IF done THEN
      LEAVE read_loop;
    END IF;
    INSERT INTO table_B(ID, VAL) VALUES(cursor_ID, cursor_VAL);
  END LOOP;
  CLOSE cursor_i;
END;
;;

请记住,将使用的变量声明为与查询表中的变量相同的类型。

我的建议是尽可能使用基于集合的查询,并且只在必要时使用简单的循环或游标。

票数 151
EN

Stack Overflow用户

发布于 2011-04-28 19:05:52

您实际上应该使用包含两个查询(基本插入)的基于集合的解决方案:

INSERT INTO TableB (Id2Column, Column33, Column44)
SELECT id, column1, column2 FROM TableA

UPDATE TableA SET column1 = column2 * column3

而对于您的转换:

INSERT INTO TableB (Id2Column, Column33, Column44)
SELECT 
    id, 
    column1 * column4 * 100, 
    (column2 / column12) 
FROM TableA

UPDATE TableA SET column1 = column2 * column3

现在,如果您的转换比这更复杂,并且涉及多个表,请发布另一个带有详细信息的问题。

票数 20
EN

Stack Overflow用户

发布于 2011-04-28 18:57:57

游标在这里是一个选项,但通常不受欢迎,因为它们通常不能充分利用查询引擎。考虑研究“基于集合的查询”,看看您是否可以在不使用游标的情况下实现您想要做的事情。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5817395

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档