我是编码的新手,我正在尝试使用游标和循环更新下表(并且不依赖于任何行号函数)。我的表是带有id和model的汽车列。问题是我正在尝试更新具有重复数字的id列,例如表格看起来像这样。我想让ID成为主键。
ID MODEL
1 Civic
1 Accord
3 Buick
3 Corolla
3 Prius
3 Saab
我在下面试过,但它只是改变了所有的值。我究竟做错了什么?这个循环在做什么?
DECLARE
ids number;
models varchar2 (50);
previous_id number := 0;
new_id number :=0;
cursor getRow is select * from CARS;
BEGIN
open getRow;
fetch getRow into ids, models;
previous_id := ids;
loop
fetch getRow into ids, models;
if getRow%found
then
new id := previous_id +1;
if ids = previous_id
then
update CARS
set ID = new_id
where ID = previous_id;
else
previous_id := ids;
end if;
else
exit;
end if;
end loop;
close getRow;
END;
答案 0 :(得分:2)
这是实现目标的最简单方法:
update cars
set id = rownum;
这会将ID设置为唯一的,单调递增的数字。
你说你不熟悉编码,所以也许这就是你不想使用简单答案的唯一原因吗?
无论如何,您的代码无法正常工作的原因是您正在选择一组ID,然后更新它们的批次。我认为您假设您的更新只影响当前行,但它不会:它使用共享ID更新所有行。此外,您关于NEW_ID和PREVIOUS_ID的逻辑是wack:您需要仅使用一个变量来保持连续性。
如果你坚持使用循环,你需要使用FOR UPDATE游标并使用WHERE CURRENT OF来更新当前行:
DECLARE
ids number;
models varchar2 (50);
previous_id number :=0;
cursor getRow is
select * from CARS
for update of id;
BEGIN
open getRow;
fetch getRow into ids, models;
loop
if getRow%found
then
if ids = previous_id
then
previous_id := previous_id +1;
update CARS
set ID = new_id
where current of getRow;
else
previous_id := ids;
end if;
else
exit;
end if;
fetch getRow into ids, models;
end loop;
close getRow;
END;
但与纯SQL解决方案相比,这是太多的代码。它的执行速度也会慢得多。如果这是一个自学PL / SQL的玩具练习,那么这一切都不重要,但在实际应用中编码并不是那么重要。