Sql 在Oracle上使用rownum更新ID递增的表是否安全?
类似于我希望用增量值更新(填充)空列——使用Oracle。即Sql 在Oracle上使用rownum更新ID递增的表是否安全?,sql,database,oracle,auto-increment,rownum,Sql,Database,Oracle,Auto Increment,Rownum,类似于我希望用增量值更新(填充)空列——使用Oracle。即 ALTER TABLE data ADD ( id number ); 我希望ID列中的所有记录都能接收唯一的值。之后,我将启用NOTNULL和unique约束,使其成为主键 我很快想出了一个好主意 UPDATE TABLE data SET id = rownum; 但是我有一种不好的感觉。它在我的测试中按预期工作,但示例不能证明:-) 在update-语句中以这种方式使用rownum安全吗?可能,您的方法是安全的。否则,
ALTER TABLE data ADD
(
id number
);
我希望ID
列中的所有记录都能接收唯一的值。之后,我将启用NOTNULL和unique约束,使其成为主键
我很快想出了一个好主意
UPDATE TABLE data SET id = rownum;
但是我有一种不好的感觉。它在我的测试中按预期工作,但示例不能证明:-)
在
update
-语句中以这种方式使用rownum
安全吗?可能,您的方法是安全的。否则,如果唯一约束失败,将通知您:-)
防弹方法如下:
lock table data in exclusive mode;
merge into data t
using (select t.rowid rid, t.rownum id from data t) s
on (t.rowid = s.rid)
when matched then update set
t.id = s.id;
commit;
是的,我从来没有遇到过该方法的问题,但是启用NOTNULL和unique约束并不会使其成为主键——添加主键约束会使其成为主键;) 不,它不安全,因为ROWNUM是伪列。意味着它不能保证顺序,尤其是与ORDER BY一起使用时。如果必须,则使用ROW_NUMBER()代替ROWNUM(按_字段排序)。您也可以在循环中使用PL/SQL更新表。不需要
合并
,简单的更新也可以完成同样的事情。这是初始问题中的更新
。这将是非常好的(您的合并
将做完全相同的事情-只是稍微复杂一点)。您要防止什么?防止另一个会话同时修改同一个表(这可能导致id
列中的空值)。唯一约束也应该在提交之前设置(或代替提交)。从这个意义上说,锁使它更健壮,但我认为合并不是。它对于预期目的是安全的。如果“your_field”和主键值之间存在某种隐含的关联,那么它就不是一个很好的“无意义”主键,我想。至少你的回答告诉我,我的担心并非完全没有根据。@a_horse_和_no_name-如果你在伪列和序列和函数(如row_number())之间有选择,那么使用伪列永远都不安全,也不可取。如果您有row_number(),那么使用rownum有什么意义?固执?不考虑未来的影响?有人能确定未来的影响吗?这是/是我的观点和观点。row\u number()
函数可能由于所需的顺序而更昂贵(=更慢)rownum
可以“动态”计算,无需任何额外开销。在这种情况下,使用@knagaev是安全的,这是另一个问题,与此无关。无论如何,我必须填充现有行的数据单元格。为什么不同?您可以使用“更新表数据集id=seq.nextval”获得所需的唯一值。这将是交易安全的解决方案。@knagaev哦,谢谢你的解释,我必须尝试一下(我现在不在DB附近)。我假设seq.nextval
只会被评估一次。请仔细看看Oracle中的序列-这是一件重要的事情。它们工作速度非常快,可以避免事务隔离方面的潜在问题。@knagaev是的,我也不喜欢max(id)+1
:-)我试过了,效果不错。