将新列添加到 Oracle 表后生成主键值
Posted
技术标签:
【中文标题】将新列添加到 Oracle 表后生成主键值【英文标题】:Generating primary key values after new column has been added to Oracle table 【发布时间】:2011-06-20 10:43:30 【问题描述】:我有一个包含 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伪列的帮助下不产生预期的主键值?它必须是与rownum相关的问题。
【问题讨论】:
意外的结果是什么? Rownum 在返回结果时分配。因此,您永远不能执行SELECT ... WHERE rownum < 1
,因为如果至少有一行,那么第一行的 rownum 必须等于 1。
StevieG:除第一行外,所有行都具有相同的主键值。第一行有数字 1,其他行有 cnt 变量。
【参考方案1】:
Rownum 是一个伪列。将其分配给从选择返回的行。因此,您不能说“select * from my_table where rownum = 42”,因为尚未定义 rownum=42 的行,它会根据您的选择和谓词而有所不同(以及“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;
这假设您有足够的回滚来更新整个表。
希望对您有所帮助。
【讨论】:
效果很好,我会使用它!谢谢! Peter Lang 建议使用非常简单的解决方案来代替这个。当 UPDATE 语句需要更复杂时,使用 cursor 和 rowid 是更有效的方式。【参考方案2】:你不能这样使用ROWNUM
(见ROWNUM in SQL)。
你可以这样做:
UPDATE sometable SET id = ROWNUM;
【讨论】:
其实补起来太简单了,但为了这个任务,它是可以接受的:) @reforrer:不确定你的意思。怎么可能太简单了?以上是关于将新列添加到 Oracle 表后生成主键值的主要内容,如果未能解决你的问题,请参考以下文章