Проблема в том, как вы зацикливаетесь внутри цикла;что вам действительно нужно сделать, это определить столбцы для обновления и отдельно, а затем выполнить цикл по каждому набору столбцов для выполнения обновлений.
Еще лучше было бы выполнить всю работу в одном обновлении,например, так:
-- should error with "Invalid columns specified" due to final proc call,
-- but should update the two rows accordingly
DECLARE
TYPE col_array IS TABLE OF VARCHAR2(30) INDEX BY pls_INTEGER;
v_cols_to_update_arry col_array;
v_cols_update_from_arry col_array;
PROCEDURE update_cols (p_id IN INTEGER,
p_drp1 IN VARCHAR2,
p_drp2 IN VARCHAR2,
p_drp3 IN VARCHAR2,
p_drp4 IN VARCHAR2)
IS
v_sql CLOB := 'UPDATE alsi_bedarfsplanung SET '||CHR(10);
BEGIN
SELECT column_id
BULK COLLECT INTO v_cols_to_update_arry
FROM alsi_bedarfsplanung
UNPIVOT (column_val FOR column_id IN (kw_01, kw_02, kw_03, kw_04, kw_05, kw_06, kw_07, kw_08))
WHERE column_id BETWEEN p_drp1 AND p_drp2
AND id = p_id;
SELECT column_id
BULK COLLECT INTO v_cols_update_from_arry
FROM alsi_bedarfsplanung
UNPIVOT (column_val FOR column_id IN (kw_01, kw_02, kw_03, kw_04, kw_05, kw_06, kw_07, kw_08))
WHERE column_id BETWEEN p_drp3 AND p_drp4
AND id = p_id;
IF v_cols_to_update_arry.count > 0
AND v_cols_update_from_arry.count > 0
AND v_cols_to_update_arry.count = v_cols_update_from_arry.count THEN
FOR i IN 1..v_cols_to_update_arry.count
LOOP
if i = 1 then
v_sql := v_sql || ' ' || v_cols_to_update_arry(i) || ' = ' || v_cols_update_from_arry(i);
else
v_sql := v_sql || ',' || CHR(10) || ' ' || v_cols_to_update_arry(i) || ' = ' || v_cols_update_from_arry(i);
end if;
END LOOP;
v_sql := v_sql || chr(10) || 'where id = :p_id';
EXECUTE IMMEDIATE v_sql USING p_id;
ELSE
raise_application_error(-20001, 'Invalid columns specified');
END IF;
END update_cols;
BEGIN
update_cols (p_id => 1,
p_drp1 => 'KW_04',
p_drp2 => 'KW_06',
p_drp3 => 'KW_01',
p_drp4 => 'KW_03');
COMMIT;
update_cols (p_id => 2,
p_drp1 => 'KW_05',
p_drp2 => 'KW_08',
p_drp3 => 'KW_01',
p_drp4 => 'KW_04');
COMMIT;
update_cols (p_id => 1,
p_drp1 => 'KW_01',
p_drp2 => 'KW_02',
p_drp3 => 'KW_05',
p_drp4 => 'KW_05');
END;
/
Это работает путем выборки каждого списка столбцов в отдельный массив, циклически перебирая массивы для создания списка обновляемых столбцов, прежде чем объединять его в оператор обновления.
Вот демонстрация того, как это работает