我有一个包含2个varchar2列的表。我已将新的数字列添加到现有表中以使此列成为主键。该表现在包括3列。我尝试使用匿名块如下:
declare
cnt number;
begin
select nvl(count(*),0) into cnt from sometable;
for i in 1..cnt
loop
update sometable set id=i where i=rownum;
end loop;
end;
使用此匿名块意外更新此表
我的解决方案是使用以下声明:
create table sometablecopy as select row_number() over(order by sometable.col1) as id, sometable.* from sometable;
不过我很好奇为什么匿名块在rownum pseudocolumn的帮助下不会产生预期的主键值?它必须是rownum相关的问题。
答案 0 :(得分:1)
答案 1 :(得分:1)
Rownum是一个伪列。它从select中返回时分配给行。所以你不能说“select * from my_table where rownum = 42”因为rownum = 42的行还没有定义,它会根据你的select和谓词而变化(并且“select * from my_table where rownum = 1 “将返回单行,而不是”第一“行,无论那是什么)。你可以做一些像(未经测试的):
declare
cursor sel_cur is
select rowid as row_id
from my_table
order by orderby_col;
v_ctr pls_integer := 0;
begin
for rec in sel_cur
loop
v_ctr := v_ctr + 1;
update my_table set pk_col = v_ctr where rowid = rec.row_id;
end loop;
commit;
exception
when others then
rollback;
raise;
end;
这假设您有足够的回滚来更新整个表。
希望有所帮助。