Оскільки пропозиція циклу передбачає запит на рішення типу процедури. Ось моя.
Будь-який запит, який працює з будь-яким окремим записом, взятим із таблиці, може бути обгорнутий процедурою, щоб зробити його таким, що проходить через кожен рядок таблиці:
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;
;;
Не забудьте оголосити змінні, які ви будете використовувати, такими ж типовими, як і ті, що містяться в запитаних таблицях.
Моя порада полягає в тому, щоб, коли це можливо, іти із заданими запитами і використовувати лише прості цикли або курсори, якщо це потрібно.