Da der Vorschlag einer Schleife die Anforderung einer Lösung vom Prozedurtyp impliziert. Hier ist mein.
Jede Abfrage, die mit einem einzelnen Datensatz aus einer Tabelle funktioniert, kann in eine Prozedur eingeschlossen werden, damit sie wie folgt durch jede Zeile einer Tabelle läuft:
DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;
Dann ist hier die Prozedur gemäß Ihrem Beispiel (Tabelle_A und Tabelle_B zur Verdeutlichung verwendet)
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;
;;
Vergessen Sie dann nicht, das Trennzeichen zurückzusetzen
DELIMITER ;
Führen Sie die neue Prozedur aus
CALL ROWPERROW();
In der Zeile "INSERT INTO", die ich einfach aus Ihrer Beispielanfrage kopiert habe, können Sie tun, was Sie möchten.
Beachten Sie sorgfältig, dass die hier verwendete Zeile "INSERT INTO" die Zeile in der Frage widerspiegelt. Gemäß den Kommentaren zu dieser Antwort müssen Sie sicherstellen, dass Ihre Abfrage für jede von Ihnen ausgeführte SQL-Version syntaktisch korrekt ist.
In dem einfachen Fall, in dem Ihr ID-Feld inkrementiert ist und bei 1 beginnt, könnte die Zeile im Beispiel wie folgt lauten:
INSERT INTO table_B(ID, VAL) VALUES(ID, VAL) FROM table_A WHERE ID=i;
Ersetzen der Zeile "SELECT COUNT" durch
SET n=10;
Ermöglicht es Ihnen, Ihre Abfrage nur für die ersten 10 Datensätze in table_A zu testen.
Eine letzte Sache. Dieser Prozess ist auch sehr einfach in verschiedene Tabellen zu verschachteln und war die einzige Möglichkeit, einen Prozess für eine Tabelle auszuführen, bei dem aus jeder Zeile einer übergeordneten Tabelle dynamisch unterschiedliche Anzahlen von Datensätzen in eine neue Tabelle eingefügt wurden.
Wenn Sie es benötigen, um schneller zu laufen, versuchen Sie auf jeden Fall, es set-basiert zu machen. Wenn nicht, ist dies in Ordnung. Sie können das Obige auch in Cursorform umschreiben, aber es kann die Leistung nicht verbessern. z.B:
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;
;;
Denken Sie daran, die Variablen, die Sie verwenden, als denselben Typ wie die aus den abgefragten Tabellen zu deklarieren.
Mein Rat ist, mit setbasierten Abfragen zu arbeiten, wenn Sie können, und nur einfache Schleifen oder Cursor zu verwenden, wenn Sie müssen.