关闭

Ask Tom 之中英对照20051213——使用rowid定位行是否可靠

452人阅读 评论(0) 收藏 举报

Ask Tom 之中英对照20051213——使用rowid定位行是否可靠

http://server.it168.com/server/2005-12-29/20051229144001.shtml

Alexander

  使用rowid定位行是否可靠

  版本9.2.0

  原提交于美国东部时间2005年12月12日11:15,最新更新于2005年12月12日16:13

  问:

  你好Tom,

  我在看一个客户端应用,它需要取包括ROWID在内的若干列,然后用ROWID来定位需要更新的行。

  update some_table t set col1=value1

  where t.rowid = :selected_rowid

  这样做安全么?如果表被修改过,一行的ROWID会改变么?

  我做了一些研究:

  create table a(i number, c varchar2(250));

  insert into a select some_numeric_column, ''a'' from table_500K_rows;

  commit;

  select rowid r,i,c from a where rownum<100;

  然后我修改几行:

  update a

  set c='';asdfha sdfhaj sdhf asdhlf asldfh ajlskdfh jklasdh fjasdhf jlaksh dfjlashdfjashdfa sdjklfhalsdfhajlsdhflashdflasdhflasd''

  where i<200;

  commit;

  然后重复如下的select:

  select rowid r,i,c from a where rownum<100;

  我得到了不同的行,所以我猜想我将c更新为一个大值时分割了页,但rowid保留未变:

  select rowid r,i,c from a where i<100

  返回了相同的行和相同的rowid。ROWID会改变么?如果是,我如何简单的再现?

  谢谢你。

  答:

  一个rowid在插入时分配给一行,除非该行被删除并重新插入(就是说它是另一行,不再是原来那行了),rowid会保持不变。

  但是如果DBA或表的所有者设置了表的"enable row movement"属性,行可能被多个命令“透明的”删除+插入。

  就是说,

  如果你更新分区关键字会导致行从一个分区转移到另一个分区,分区表中的行的rowid会改变。

  如果你使用了alter table t shrink space compact,rowid会改变

  如果你使用了alter table t move,rowid会改变

  如果你使用了flashback table t to ....,rowid会改变

  但是如果你将rowid和主键一起使用,那在任何情况下都是十分安全的:

  update t

    set...

  where rowid = :x and primary_key = :pk;

  我们可以使用rowid来找到行(速度快),认为它还在那里并更新它。注意,你还是需要考虑结合对更新丢失的保护!!!你不能只是用rowid和主键来修改——除非你在读出行时锁住它,否则你将覆盖其他用户的更新。

  --------------------------------------------------------------------------------

  评论

  Single update statement?  December 12, 2005

  评论者:Greg来自多伦多

  Tom,对于单一一条update语句这也是个问题么?

  例如:

  Update some_table

    set value = something

  where rowid in ( select rowid from some_table where some_critieria);

  仅一条语句?Rollback/Undo将为我们保留记录,是么?这里rowid是“安全”的吧。

  回复:

  in this case rowid is "safe" but perhaps not "efficient"

  这里rowid是“安全”的,但可能不是“高效”的。

  update t

  set value = something

  where some_criteria;

  除非子查询有分析(analytics)或类似的东西……

  What about page splits?  December 12, 2005

  评论者:Alexander来自芝加哥

  Tom,

  谢谢你的解释。

  当我更新窄行,将c设为更宽的值时,发生了哪些(操作)?有页分割么?如果页被分割了,ROWID没有改变,那ROWID内在含义究竟是什么?

  回复:

  行迁移。

  在本站搜索"row migration",或者看看Expert one on one Oracle或Oracle: Database Architecture,我详细的进行了讲解。

  即便行迁移了,ROWID是不变的。

  Different row, same rowid  December 12, 2005

  评论者:一个读者来自加州圣弗朗西斯科

  ROWID在如下情况中也是不可靠的。

  会话1: 获取一行和rowid X

  会话2:删除rowid X的行,提交

  /* rowid X 此时可以自由重用 */

  会话3: 插入rowid为X的新行,提交

  会话1: update .... where rowid = X

  会话1的更新不是更新早前取出的同一行了。

  回复:

  这就是为什么我上面提到需要主键。

  ....

  但是如果你将rowid和主键一起使用,那在任何情况下都是十分安全的

  .....

  --------------------------------------------------------------------------------

  --------------------------------------------------------------------------------

  原文标题:

  Alexander -- Thanks for the question regarding "Is it safe to use ROWID to locate a row?", version 9.2.0

  原文地址:

  http://asktom.oracle.com/pls/ask ... AYID:53140678334596

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:658780次
    • 积分:9889
    • 等级:
    • 排名:第1825名
    • 原创:254篇
    • 转载:574篇
    • 译文:0篇
    • 评论:9条