使用“where”子句中的“in”运算符更新行

时间:2010-04-19 19:13:11

标签: sql oracle subquery

我偶然发现了我不理解的SQL行为。我需要一次更新表中的几行;刚开始找到它们:

SELECT * FROM some_table WHERE field1 IN (SELECT ...)

这返回了大约60行的选择。现在我非常自信我得到了子查询,所以我修改了仅第一部分

UPDATE some_table SET field2 = some_value WHERE field1 IN (SELECT ...)

换句话说,这与WHERE之后的第一个查询完全相同。但是,它导致0行更新,而我预计会有60行。请注意,上面的语句将更改field2,即我确认some_value中没有WHERE选定的行。

子查询是一个非常复杂的SQL文件,包含2个(不同的)表,1个视图,连接和它自己的UPDATE子句。如果这很重要,那就是Oracle Database 10g。

所以,问题是,为什么SELECT没有触及{{1}} 返回的行?

5 个答案:

答案 0 :(得分:4)

最后把它钉了下来。原来,子查询选择中使用的视图间接(通过另一个视图)称为存储过程/函数。然后,该过程访问了UPDATE中正在修改的表。结果,Oracle抛出异常,因为“表some_table正在被修改,函数可能看不到结果”(不记得确切的文本)。但函数最后使用when other then return null,因此错误被有效隐藏,子查询根本没有返回任何内容 - 反过来UPDATE没有效果。

道德:永远不要使用过于宽泛的异常捕手。我在其他语言中遵循此规则,但显然不在PL / SQL中: - /

答案 1 :(得分:1)

如果“some-table”实际上是一个视图,那么您可能遇到了系统无法解决如何更新视图基础的表的问题。

答案 2 :(得分:1)

我有一个问题,一次我输错了一个列名,但是另一个选择中有一个同名的列,所以我的内部查询通过加入外表来“工作”。
如果你只是自己运行内部查询(没有外部选择或更新)它是否有效?

答案 3 :(得分:0)

可能是行级安全性(也称为虚拟专用数据库),您可以在其中获得读取表行的权限,但不能更新它们。

是否涉及任何数据库链接?

答案 4 :(得分:0)

你的field1不是从子查询返回的第一列吗?我怀疑你的IN只会将值与结果的第一列进行比较。