sql >> Database teknologi >  >> RDS >> Mysql

Hvordan kan jeg gå gennem alle rækker i en tabel? (MySQL)

Da forslaget om en løkke indebærer anmodningen om en løsning af proceduretypen. Her er min.

Enhver forespørgsel, der fungerer på en enkelt post taget fra en tabel, kan pakkes ind i en procedure for at få den til at køre gennem hver række i en tabel sådan:

Slet først enhver eksisterende procedure med samme navn, og skift afgrænseren, så din SQL ikke forsøger at køre hver linje, mens du prøver at skrive proceduren.

DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;

Så her er proceduren som i dit eksempel (tabel_A og tabel_B brugt for klarhed)

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

Så glem ikke at nulstille afgrænseren

DELIMITER ;

Og kør den nye procedure

CALL ROWPERROW();

Du kan gøre, hvad du vil på linjen "INSERT INTO", som jeg blot kopierede fra din eksempelanmodning.

Bemærk OMHYGGELIGT, at linjen "INSERT INTO" brugt her afspejler linjen i spørgsmålet. I henhold til kommentarerne til dette svar skal du sikre dig, at din forespørgsel er syntaktisk korrekt for hvilken version af SQL du kører.

I det simple tilfælde, hvor dit ID-felt øges og starter ved 1, kunne linjen i eksemplet blive:

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

Udskiftning af "SELECT COUNT"-linjen med

SET n=10;

Vil kun lade dig teste din forespørgsel på de første 10 post i tabel_A.

En sidste ting. Denne proces er også meget nem at indlejre på tværs af forskellige tabeller og var den eneste måde, jeg kunne udføre en proces på én tabel, som dynamisk indsatte forskellige antal poster i en ny tabel fra hver række i en overordnet tabel.

Hvis du har brug for det til at køre hurtigere, så prøv at gøre det indstillet baseret, hvis ikke, så er det fint. Du kan også omskrive ovenstående i markørform, men det forbedrer muligvis ikke ydeevnen. f.eks.:

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

Husk at erklære de variabler, du vil bruge, som den samme type som dem fra de forespurgte tabeller.

Mit råd er at gå med sætbaserede forespørgsler, når du kan, og kun bruge simple loops eller markører, hvis du er nødt til det.



  1. Min MySQL-database er løbet tør for diskplads

  2. PostgreSQL Upsert differentiere indsatte og opdaterede rækker ved hjælp af systemkolonner XMIN, XMAX og andre

  3. Formater SQL-tabeldata som teksttabel

  4. hvordan ændres postgresql lytteport i Windows?