首页 » 编程开发 » ORACLE » 正文

ORACLE两表联合更新FOR UPDATE方法及ORA-01410: invalid ROWID解决方法

ORACLE两表联合更新是经常会遇到的情况,我们经常会使用的方法是这样的:

update table_a
set …
where … and exists(select 1 from table_b where table_a.col = table_b.col and …)

这可以说是oracle下两表联合更新的标准用法:通过exist实现。

这种方法下,如果我只需要更新两个表中一个表的字段,那是非常恰当,但如果我需要将两个表的字段都更新一下,如果用上面的方法,我将需要写两个sql,是不是很麻烦,特别对于初学者来说,直接将需要更新的数据通过for update语句查询出来,直接修改,将非常方便。但使用for update来查询更新数据,试过这种方法的童鞋都知道,这样会报错:“ORA-01410: invalid ROWID”,本文告诉你怎么来解决这个问题。
实验第一步,准备两张数据表:
temp_test1
————————-
SID STEXT
1 123445
2 4345545
3 ref34rf34f
————————-

 

temp_test2
————————-
SID SNUMBER
1 888888
2 9999999
4 3333333
————————-

执行:SELECT * FROM temp_test1 a,temp_test2 b WHERE a.sid=b.sid FOR UPDATE,将查询结果数据修改一下,提交,弹出错误:
1

下面将sql语句修改成下面这样:

SELECT a.rowid,a.*,b.* FROM temp_test1 a,temp_test2 b WHERE a.sid=b.sid FOR UPDATE

现在再来修改第一个表的数据,提交,竟然成功了。
经过测试,还是有个问题,那就是第二个表temp_test2的SNUMBER字段是number类型的,使用这种方法是不能修改的,也就是说,这种方法只能针对字符型字段进行修改。

总结一下:为什么不在sql语句中加入rowid查询,就会报错呢?那是因为两个表关联查询for update,单表for update能更新的原理也就是oracle自动帮你将它转换成update的sql语句,然后提交,但是两个表的话,oracle也不知道你要修改的是哪个表的数据,所以就会报错咯,加入temp_test1表的rowid之后,oracle就会自动默认你是为了更新temp_test1表,所以同理,如果你想更新第二个表temp_test2,那么就a.rowid换成b.rowid,就可以了,很简单。
rowid在oracle中是一个伪列,它指的是表中记录存储的实际物理地址。

本文共 3 个回复

  • 坛子 2015/12/21 17:26

    😎

  • smiler 博主 2015/12/21 18:00

    1

发表评论