sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo puedo recorrer todas las filas de una tabla? (MySQL)

Ya que la sugerencia de un bucle implica la solicitud de una solución de tipo procedimiento. Aquí está el mío.

Cualquier consulta que funcione en cualquier registro único tomado de una tabla se puede incluir en un procedimiento para que se ejecute en cada fila de una tabla de la siguiente manera:

Primero elimine cualquier procedimiento existente con el mismo nombre y cambie el delimitador para que su SQL no intente ejecutar cada línea mientras intenta escribir el procedimiento.

DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;

Luego, aquí está el procedimiento según su ejemplo (tabla_A y tabla_B usadas para mayor claridad)

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;
;;

Entonces no olvide restablecer el delimitador

DELIMITER ;

Y ejecute el nuevo procedimiento

CALL ROWPERROW();

Puede hacer lo que quiera en la línea "INSERTAR EN" que simplemente copié de su solicitud de ejemplo.

Tenga en cuenta CUIDADOSAMENTE que la línea "INSERTAR EN" utilizada aquí refleja la línea en la pregunta. Según los comentarios de esta respuesta, debe asegurarse de que su consulta sea sintácticamente correcta para cualquier versión de SQL que esté ejecutando.

En el caso simple en el que su campo de ID se incrementa y comienza en 1, la línea del ejemplo podría convertirse en:

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

Reemplazo de la línea "SELECT COUNT" con

SET n=10;

Le permitirá probar su consulta solo en los primeros 10 registros de la tabla_A.

Una última cosa. Este proceso también es muy fácil de anidar en diferentes tablas y era la única forma en que podía llevar a cabo un proceso en una tabla que insertaba dinámicamente diferentes números de registros en una nueva tabla desde cada fila de una tabla principal.

Si necesita que se ejecute más rápido, intente configurarlo en función de la configuración, si no, está bien. También puede volver a escribir lo anterior en forma de cursor, pero es posible que no mejore el rendimiento. por ejemplo:

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;
;;

Recuerde declarar las variables que utilizará como del mismo tipo que las de las tablas consultadas.

Mi consejo es ir con consultas basadas en conjuntos cuando pueda, y solo use bucles o cursores simples si es necesario.