我想在像这样的桌子上的一个巨大的桌子上执行更新(我现在不是最好的做法):
TARGET_TABLE (
TICKET_ID number,
product_id number,
NET number(15,2),
VAT number(15,2));
http://sqlfiddle.com/#!4/d39ed/3
目标:UPDATE TARGET_TABLE set NET=VAT, VAT=NET
我想出了一个批量更新,但我在第43行得到了ORA-00913:“ To many values”,我无法解释。另外,我不知道如何在该变体中一次更新两行。 有人可以帮忙吗?
DECLARE
-- new data
CURSOR new_data_cur IS
select
a.rowid,
a.TICKET_ID,
a.product_id,
b.NET,
b.VAT
from TARGET_TABLE a
join TARGET_TABLE_COPY b
on ( a.TICKET_ID=b.TICKET_ID AND a.product_id =b.product_id ) ;
TYPE new_data_type IS TABLE OF new_data_cur%rowtype INDEX BY PLS_INTEGER;
new_data_tab new_data_type;
TYPE row_id_type IS TABLE OF ROWID INDEX BY PLS_INTEGER;
row_id_tab row_id_type;
TYPE rt_update_cols IS RECORD (
NET TARGET_TABLE.NET%TYPE
-- VAT TARGET_TABLE.VAT%TYPE
);
TYPE update_cols_type IS
TABLE OF rt_update_cols INDEX BY PLS_INTEGER;
update_cols_tab1 update_cols_type;
--update_cols_tab2 update_cols_type;
dml_errors EXCEPTION;
PRAGMA exception_init ( dml_errors,-24381 );
BEGIN
OPEN new_data_cur;
LOOP
FETCH new_data_cur BULK COLLECT INTO new_data_tab LIMIT 50000;
EXIT WHEN new_data_tab.count=0;
FOR i IN new_data_tab.first..new_data_tab.last LOOP
row_id_tab(i) := new_data_tab(i).rowid;
update_cols_tab1(i).NET := new_data_tab(i).VAT;
-- update_cols_tab2(i).VAT := new_data_tab(i).NET;
END LOOP;
FORALL i IN new_data_tab.first..new_data_tab.last SAVE EXCEPTIONS # ORA-00913: To many values
UPDATE TARGET_TABLE
-- SET row = update_cols_tab(i)
SET row = update_cols_tab1(i)
-- row = update_cols_tab2(i)
WHERE ROWID = row_id_tab(i);
COMMIT;
EXIT WHEN new_data_tab.count=0;
END LOOP;
COMMIT;
CLOSE new_data_cur;
EXCEPTION
WHEN dml_errors THEN
FOR i IN 1..SQL%bulk_exceptions.count LOOP
dbms_output.put_line('Some error occured');
END LOOP;
END;
答案 0 :(得分:0)
我相信您在交换值的地方不需要多余的光标
FOR i IN new_data_tab.first..new_data_tab.last LOOP
row_id_tab(i) := new_data_tab(i).rowid;
update_cols_tab1(i).NET := new_data_tab(i).VAT;
-- update_cols_tab2(i).VAT := new_data_tab(i).NET;
END LOOP;
因此您的代码将在批量更新中使用这些值
DECLARE
-- new data
CURSOR new_data_cur IS
select
a.rowid,
a.TICKET_ID,
a.product_id,
b.NET,
b.VAT
from TARGET_TABLE a
join TARGET_TABLE_COPY b
on ( a.TICKET_ID=b.TICKET_ID AND a.product_id =b.product_id ) ;
TYPE new_data_type IS TABLE OF new_data_cur%rowtype INDEX BY PLS_INTEGER;
new_data_tab new_data_type;
TYPE row_id_type IS TABLE OF ROWID INDEX BY PLS_INTEGER;
row_id_tab row_id_type;
TYPE rt_update_cols IS RECORD (
NET TARGET_TABLE.NET%TYPE
-- VAT TARGET_TABLE.VAT%TYPE
);
TYPE update_cols_type IS
TABLE OF rt_update_cols INDEX BY PLS_INTEGER;
update_cols_tab1 update_cols_type;
--update_cols_tab2 update_cols_type;
dml_errors EXCEPTION;
PRAGMA exception_init ( dml_errors,-24381 );
BEGIN
OPEN new_data_cur;
LOOP
FETCH new_data_cur BULK COLLECT INTO new_data_tab LIMIT 50000;
EXIT WHEN new_data_tab.count=0;
FORALL i IN new_data_tab.first..new_data_tab.last SAVE EXCEPTIONS # ORA-00913: To many values
UPDATE TARGET_TABLE
-- SET row = update_cols_tab(i)
-- SET row = update_cols_tab1(i)
-- row = update_cols_tab2(i)
NET = update_cols_tab1(i).VAT
VAT = update_cols_tab1(i).NET
WHERE ROWID = row_id_tab(i);
COMMIT;
EXIT WHEN new_data_tab.count=0;
END LOOP;
COMMIT;
CLOSE new_data_cur;
EXCEPTION
WHEN dml_errors THEN
FOR i IN 1..SQL%bulk_exceptions.count LOOP
dbms_output.put_line('Some error occured');
END LOOP;
END;