Поскольку предложение цикла подразумевает запрос решения типа процедуры.Вот мое.
Любой запрос, который работает с любой отдельной записью, взятой из таблицы, может быть заключен в процедуру, чтобы он выполнялся через каждую строку таблицы следующим образом:
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;
Замена строки «SELECT COUNT» на
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;
;;
Не забудьте объявить переменные, которые вы будете использовать, того же типа, что и переменные из запрашиваемых таблиц.
Я советую выполнять запросы на основе набора, когда это возможно, и толькоиспользуйте простые циклы или курсоры, если вам нужно.