Ponieważ sugestia pętli implikuje żądanie rozwiązania typu procedury. Tu jest moje.
Każde zapytanie, które działa na każdym pojedynczym rekordzie pobranym z tabeli, można opakować w procedurę, aby przeszło przez każdy wiersz tabeli w następujący sposób:
DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;
Oto procedura jak na twoim przykładzie (tabela_A i tabela_B użyte dla przejrzystości)
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;
;;
Następnie nie zapomnij zresetować ogranicznika
DELIMITER ;
I uruchom nową procedurę
CALL ROWPERROW();
Możesz zrobić, co chcesz, w wierszu „INSERT INTO”, który po prostu skopiowałem z Twojego przykładowego żądania.
Zauważ UWAŻNIE, że użyty tutaj wiersz "INSERT INTO" odzwierciedla wiersz w pytaniu. Zgodnie z komentarzami do tej odpowiedzi, musisz upewnić się, że twoje zapytanie jest poprawne składniowo dla każdej używanej wersji SQL.
W prostym przypadku, gdy pole ID jest zwiększane i zaczyna się od 1, wiersz w przykładzie mógłby wyglądać następująco:
INSERT INTO table_B(ID, VAL) VALUES(ID, VAL) FROM table_A WHERE ID=i;
Zastąpienie wiersza „WYBIERZ LICZNIK” znakiem
SET n=10;
Pozwoli Ci przetestować zapytanie tylko na pierwszych 10 rekordach w tabeli_A.
Ostatnia rzecz. Ten proces jest również bardzo łatwy do zagnieżdżenia w różnych tabelach i był to jedyny sposób, w jaki mogłem przeprowadzić proces na jednej tabeli, który dynamicznie wstawiał różne liczby rekordów do nowej tabeli z każdego wiersza tabeli nadrzędnej.
Jeśli chcesz, aby działał szybciej, spróbuj ustawić go na podstawie zestawu, jeśli nie, to jest w porządku. Możesz również przepisać powyższe w formie kursora, ale może to nie poprawić wydajności. na przykład:
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;
;;
Pamiętaj, aby zadeklarować zmienne, których będziesz używać, jako tego samego typu, co zmienne z odpytywanych tabel.
Radzę korzystać z zapytań opartych na ustawieniach, kiedy tylko możesz, i używać tylko prostych pętli lub kursorów, jeśli musisz.