Поскольку предложение цикла подразумевает запрос решения типа процедуры. Вот мой.
Любой запрос, который работает с любой отдельной записью, взятой из таблицы, можно обернуть в процедуру, чтобы он проходил через каждую строку таблицы следующим образом:
DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;
Тогда вот процедура в соответствии с вашим примером (table_A и table_B используются для ясности)
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;
;;
Тогда не забудьте сбросить разделитель
DELIMITER ;
И запускаем новую процедуру
CALL ROWPERROW();
Вы можете делать все, что хотите, в строке «INSERT INTO», которую я просто скопировал из вашего примера запроса.
ВНИМАТЕЛЬНО обратите внимание на то, что использованная здесь строка «INSERT INTO» отражает строку в вопросе. В соответствии с комментариями к этому ответу вам необходимо убедиться, что ваш запрос синтаксически верен для какой-либо версии SQL, которую вы используете.
В простом случае, когда поле вашего идентификатора увеличивается и начинается с 1, строка в примере может выглядеть так:
INSERT INTO table_B(ID, VAL) VALUES(ID, VAL) FROM table_A WHERE ID=i;
Замена строки «ВЫБРАТЬ СЧЕТЧИК» на
SET n=10;
Позволит вам протестировать ваш запрос только на первых 10 записях в table_A.
Последняя вещь. Этот процесс также очень легко вложить в разные таблицы, и это был единственный способ выполнить процесс для одной таблицы, который динамически вставлял разное количество записей в новую таблицу из каждой строки родительской таблицы.
Если вам нужно, чтобы он работал быстрее, обязательно попробуйте настроить его на основе, если нет, тогда это нормально. Вы также можете переписать приведенное выше в форме курсора, но это не может улучшить производительность. например:
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;
;;
Не забудьте объявить переменные, которые вы будете использовать, того же типа, что и переменные из запрашиваемых таблиц.
Я советую использовать запросы на основе наборов, когда это возможно, и использовать только простые циклы или курсоры, если это необходимо.