对于x行后的更新,我发现了这一点:
DECLARE
i NUMBER := 0;
CURSOR G1 IS SELECT * FROM test_new
FOR UPDATE;
BEGIN
FOR c1 IN S1 LOOP
UPDATE test SET col1 = 'somevalue1'
WHERE CURRENT OF G1;
i := i + 1; -- Commits after every X number of records
IF i > 1000 THEN
COMMIT;
i := 0;
END IF;
END LOOP;
COMMIT;
END;
要用另一个表更新一个表,此代码有效:
DECLARE
l_r_id test_new.id_customer%type;
l_r_name test_new.name%type;
i NUMBER := 0;
CURSOR CUR is select tnw.id_customer, tnw.name
from test_new tnw
, test tes
where tnw.id_customer = tes.id_customer
FOR UPDATE;
BEGIN
OPEN cur;
LOOP
FETCH cur
INTO l_r_id, l_r_name;
UPDATE test
set name = l_r_name
where test.id_customer = l_r_id;
i := i+1;
EXIT WHEN cur%notfound;
END LOOP;
commit;
END;
但是我不知道如何获得
IF i > 50000 THEN
COMMIT;
i := 0;
END IF;
输入代码。 FETCH和Commit似乎有问题。我从Oracle收到错误消息:
2)如果使用FOR UPDATE子句打开了游标,则在发出COMMIT后进行获取将返回错误。
有人有想法吗?我知道有一种无需“ FETCH”即可加入的方式,但我不知道如何。就像我之前说的,请仅提供代码帮助,而无需讨论更新和提交。
答案 0 :(得分:0)
Exit
必须在fetch
之后,如果光标没有数据,则循环将终止。
在循环结束时,您可以按以下方式查询提交。 所以你的循环看起来像这样
LOOP
FETCH cur
INTO l_r_id, l_r_name;
EXIT WHEN cur%notfound;
UPDATE test
set name = l_r_name
where test.id_customer = l_r_id;
i := i+1;
if mod(i,50000) = 0 then
commit;
end if;
END LOOP;
另一个建议是定义记录的集合。
用表test_new
中的数据填充集合。然后遍历此集合并进行更新。
未经测试,解决方案可能如下所示。
DECLARE
TYPE tabTest IS TABLE OF test_new%ROWTYPE;
t_test tabTest;
i NUMBER := 0;
BEGIN
select tnw.*
bulk collect into t_test
from test_new tnw
, test tes
where tnw.id_customer = tes.id_customer
for indx in 1 .. t_test.count()
loop
UPDATE test
set name = t_test(indx).name
where test.id_customer = t_test(indx).id;
i := i+1;
if mod(i,50000) = 0 then
commit;
end if;
end loop;
commit;
END;
答案 1 :(得分:0)
借助@hotfix的解决方案:
DECLARE
TYPE tabTest IS TABLE OF test_new%ROWTYPE;
t_test tabTest;
testcount number;
i NUMBER := 0;
BEGIN
select count(*) into testcount from test_new;
select tnw.*
bulk collect into t_test
from test_new tnw
, test tes
where tnw.id_customer = tes.id_customer;
FOR cur IN 1..testcount LOOP
UPDATE test
set name = t_test(cur).name
where test.id_customer = t_test(cur).id_customer;
i := i + 1; -- Commits after every X number of records
IF i > 50000 THEN
COMMIT;
i := 0;
END IF;
END LOOP;
COMMIT;
END;