将新列添加到Oracle表后生成主键值

时间:2011-06-20 10:43:30

标签: oracle

我有一个包含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相关的问题。

2 个答案:

答案 0 :(得分:1)

您不能使用ROWNUM(请参阅ROWNUM in SQL)。

你可以做的是:

UPDATE sometable SET id = ROWNUM;

答案 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;

这假设您有足够的回滚来更新整个表。

希望有所帮助。