Ponieważ sugestia pętli implikuje żądanie rozwiązania typu procedury. Oto moja.
Każde zapytanie, które działa na dowolnym pojedynczym rekordzie pobranym z tabeli, może zostać opakowane w procedurę, aby przebiegało przez każdy wiersz tabeli, jak na przykład:
Najpierw usuń istniejącą procedurę o tej samej nazwie i zmień ogranicznik, aby Twój SQL nie próbował uruchamiać każdego wiersza podczas pisania procedury.
DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;
Oto procedura według twojego przykładu (table_A i table_B użyte dla jasnoś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 „WSTAW DO”, który po prostu skopiowałem z twojego przykładowego żądania.
Zwróć uwagę, że użyta tutaj linia „INSERT INTO” odzwierciedla linię w pytaniu. Zgodnie z komentarzami do tej odpowiedzi musisz upewnić się, że zapytanie jest poprawne składniowo dla każdej wersji SQL, której używasz.
W prostym przypadku, gdy pole ID jest zwiększone i zaczyna się od 1, wiersz w przykładzie może wyglądać tak:
INSERT INTO table_B(ID, VAL) VALUES(ID, VAL) FROM table_A WHERE ID=i;
Zastąpienie wiersza „WYBIERZ LICZNIK” słowem
SET n=10;
Umożliwi przetestowanie zapytania tylko na pierwszych 10 rekordach w tabeli table_A.
Ostatnia rzecz. Ten proces jest również bardzo łatwy do zagnieżdżenia w różnych tabelach i był jedynym sposobem, 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 potrzebujesz, aby działał szybciej, spróbuj ustawić go na podstawie, 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. np.:
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 te z żądanych tabel.
Radzę korzystać z zapytań opartych na zestawach, kiedy tylko możesz, i używać tylko prostych pętli lub kursorów, jeśli to konieczne.