使用ROWID在Oracle中查找行/记录是否安全?

aur*_*ora 4 sql oracle oracle-sqldeveloper

我正在查看一个客户端应用程序,该应用程序检索多个列,包括ROWID以后用于ROWID识别需要更新的行:

update some_table t set col1=value1
where t.rowid = :selected_rowid
Run Code Online (Sandbox Code Playgroud)

这样做是否安全?随着表的修改,ROWID一行可以改变吗?

Joh*_*acs 7

"从Oracle 8开始,ROWID格式和大小从8变为10个字节.请注意,ROWID重组或导出/导入表时会发生变化.如果是分区表,如果行从分区迁移到另一个分区,它也会发生变化在一个期间UPDATE."

http://www.orafaq.com/wiki/ROWID

我会说不.如果例如应用程序ROWID临时存储(例如生成可选项目列表,每个项目都被标识ROWID,但列表经常重新生成并且未存储),这可能是安全的.但如果ROWID以任何持久的方式使用它是不安全的.


Jus*_*ave 6

假设您使用了ROWID很短的时间后SELECT,该表是一个标准的堆组织表,并且DBA没有对表执行某些操作(如果应用程序在线,这是一个相当安全的假设),ROWID将是稳定的.最好使用主键,但是当主键不可用时,许多Oracle开发的工具和框架将在ROWID短时间内使用.如果您打算ROWIDSELECT它之后使用很长一段时间,那将是不安全的- 例如,如果您允许用户在本地编辑数据,然后在一段任意长度的时间内与主数据库同步.

ROWID是行的只是一个物理位置,以便任何导致该位置变化将改变ROWID.

  • 如果您正在使用索引组织表或分区表,则对行的更新可能会更改行的物理位置,这将更改ROWID.
  • 如果从堆组织表中删除行,则后续INSERT可能会插入具有完全不同数据的数据,这些数据恰好使用ROWID先前已删除的行.
  • 各种管理任务都可能导致ROWID更改.ROWID例如,导出和导入表将改变,但是会执行类似new-ish online shrink命令的操作.但是,这些管理任务通常不会在应用程序启动时完成,并且几乎肯定不会在白天完成.但是,当DBA执行此类操作或应用程序持久保存数据时,如果应用程序未关闭,则可能会导致问题.

随着时间的推移,新功能越来越常见,为ROWIDs的变化带来了新的可能性.例如,索引组织表和在线收缩选项是相对较新的功能.在未来,可能会有更多的功能涉及潜力,至少是ROWID为了改变.

当然,如果我们迂腐,依靠主键也是不安全的.很可能一些其他会话出现并在您读取之后更新该行的主键,或者在您选择它之后某个其他会话删除该行并插入具有相同数据和不同主键的新行.在任何一种情况下,都有一些关于使用数据库的应用程序实际上应该做什么的本地知识是有帮助的.例如,允许更新主键或重用主键非常罕见,因此您通常可以确定使用主键是安全的.类似地,相对常见的结论是,鉴于您使用分区的方式或者您在索引组织表中定义索引的方式,更新实际上不会更改ROWID.LOAD_DATE例如,如果您知道该表已被分区,并且您永远不会更新该表LOAD_DATE,则ROWID由于更新,您实际上不会遇到更改.如果您知道该表是索引组织的,但您没有更新属于该索引的列,则ROWID不会更改UPDATE.