如何遍历表格的所有行?(MySQL的)

Raf*_*ael 67 mysql loops

我有一个表A,有一个主键ID.

现在我想要浏览A中的所有行.

我发现了'对于A中的每个记录',但这似乎不是你在MySQL中的表现.

我想要获取一个字段并对其进行转换,将其插入另一个表中,然后更新某些行的字段.我可以将select部分和插入放在一个语句中,但我不知道如何在那里获得更新.所以我想循环.而对于练习,我不想使用除MySQL以外的任何东西.

编辑

我会很感激一个例子.

并且不需要将其纳入程序中.

编辑2

好吧想想这个场景:

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

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

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

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

(这只是一个简化的例子,当然你不会为此使用循环.)}

Mr *_*ple 107

由于循环的建议意味着请求过程类型解决方案.这是我的.

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

DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;
Run Code Online (Sandbox Code Playgroud)

然后根据您的示例执行此过程(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;
;;
Run Code Online (Sandbox Code Playgroud)

然后别忘了重置分隔符

DELIMITER ;
Run Code Online (Sandbox Code Playgroud)

并运行新程序

CALL ROWPERROW();
Run Code Online (Sandbox Code Playgroud)

您可以在"INSERT INTO"行中执行任何您喜欢的操作,我只是从您的示例请求中复制该行.

请注意,此处使用的"INSERT INTO"行反映了问题中的行.根据对此答案的评论,您需要确保您的查询在语法上对于您正在运行的SQL版本是正确的.

在ID字段递增并从1开始的简单情况下,示例中的行可能变为:

INSERT INTO table_B(ID, VAL) VALUES(ID, VAL) FROM table_A WHERE ID=i;
Run Code Online (Sandbox Code Playgroud)

用.替换"SELECT COUNT"行

SET n=10;
Run Code Online (Sandbox Code Playgroud)

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

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

如果你需要它运行得更快,那么一定要尝试设置它,如果没有那么这很好.您也可以用光标形式重写上述内容,但可能无法提高性能.例如:

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;
;;
Run Code Online (Sandbox Code Playgroud)

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

我的建议是尽可能使用基于setbased的查询,如果必须,只使用简单的循环或游标.

  • INSERT INTO table_B(ID,VAL)VALUES(ID,VAL)FROM table_A LIMIT i,1; 给出语法错误. (2认同)

Raj*_*ore 13

您应该使用涉及两个查询的基于集合的解决方案(基本插入):

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

UPDATE TableA SET column1 = column2 * column3
Run Code Online (Sandbox Code Playgroud)

为了你的变革:

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

UPDATE TableA SET column1 = column2 * column3
Run Code Online (Sandbox Code Playgroud)

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

  • @ Raffael1984:编辑你的问题以添加"导致特定插入的特定行"的条件,我们可以提供帮助.你真的不想去光标/循环路线 - 这是非常低效的. (2认同)