例如,我想将2列在KW_01(下拉)和KW_03(下拉)之间移动到KW_04(下拉)和KW_06(下拉)之间。我在表中有53列。我写了代码(见下文),但是不幸的是它不能正常工作。当我启动代码时,他会这样做。
意外结果:
Outer Loop counter is kw_04 Inner Loop counter is 1
Outer Loop counter is kw_04 Inner Loop counter is 2
Outer Loop counter is kw_04 Inner Loop counter is 3
Outer Loop counter is kw_05 Inner Loop counter is 1
Outer Loop counter is kw_05 Inner Loop counter is 2
Outer Loop counter is kw_05 Inner Loop counter is 3
Outer Loop counter is kw_06 Inner Loop counter is 1
Outer Loop counter is kw_06 Inner Loop counter is 2
Outer Loop counter is kw_06 Inner Loop counter is 3
DECLARE
plsql VARCHAR2(500);
BEGIN
For i in (SELECT column_id
FROM alsi_bedarfsplanung unpivot(column_value FOR column_id IN("KW_01", "KW_02", "KW_03", "KW_04", "KW_05", "KW_06"))
WHERE column_id BETWEEN :drp1 AND :drp2
and id = 1)
LOOP
FOR o in (SELECT column_value
FROM alsi_bedarfsplanung unpivot(column_value FOR column_id IN("KW_01", "KW_02", "KW_03", "KW_04", "KW_05", "KW_06"))
WHERE column_id BETWEEN :drp3 AND :drp4
and id = 1)
LOOP
plsql := ' UPDATE ALSI_BEDARFSPLANUNG SET ' || i.column_id || ' = ' ||
o.column_value || ' where ID = 1 ';
EXECUTE IMMEDIATE plsql;
END LOOP;
END LOOP;
END;
我想要什么
Outer Loop counter is kw_04 Inner Loop counter is 1//(KW_1 Value)
Outer Loop counter is kw_05 Inner Loop counter is 2//(KW_2 Value)
Outer Loop counter is kw_06 Inner Loop counter is 3//(KW_3 Value)
答案 0 :(得分:0)
问题在于您在循环中循环的方式;您真正需要做的是分别识别要更新的列和从中更新的列,然后遍历每组列进行更新。
更好的做法是在一次更新中完成所有工作,就像这样:
-- 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;
/
这是通过将每个列列表提取到一个单独的数组中,然后遍历数组以建立要更新的列列表,然后再将其连接到update语句来实现的。