Ответ 1
Так как предложение цикла подразумевает запрос на решение типа процедуры. Вот моя.
Любой запрос, который работает с любой отдельной записью, взятой из таблицы, может быть завернут в процедуру, чтобы она выполнялась через каждую строку таблицы следующим образом:
DROP PROCEDURE IF EXISTS ROWPERROW;
DELIMITER ;;
Затем здесь процедура в соответствии с вашим примером (таблица_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) VALUES(ID, VAL) FROM table_A LIMIT i,1;
SET i = i + 1;
END WHILE;
End;
;;
Тогда не забудьте reset разделитель
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 записи только в таблице_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;
;;
Не забудьте объявить переменные, которые вы будете использовать в том же типе, что и те, которые указаны в запрошенных таблицах.
Моя советка состоит в том, чтобы идти с заданными вопросами, когда это возможно, и использовать только простые циклы или курсоры, если вам нужно.