代码之家  ›  专栏  ›  技术社区  ›  doublep

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

  •  4
  • doublep  · 技术社区  · 14 年前

    我偶然发现了我不理解的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 所选行中不存在。

    子查询是一个相当复杂的SQL片段,包含2个(不同的)表、1个视图、联接及其自己的 在哪里? 条款。在这种情况下,它发生在Oracle数据库10g上。

    所以,问题是, 为什么? UPDATE 没有触摸返回的行 SELECT ?

    5 回复  |  直到 14 年前
        1
  •  4
  •   doublep    14 年前

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

    道德:永远不要使用过路异常捕捉器。我在其他语言中遵循这个规则,但显然在pl/sql中没有:-/

        2
  •  1
  •   Philip Kelley    14 年前

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

        3
  •  1
  •   hamishmcn    14 年前

    我曾经遇到过一个问题,在这里我输入了错误的列名,但是在另一个select中有一个同名的列,所以我的内部查询通过与外部表联接来“工作”。
    如果您只是单独运行内部查询(没有外部选择或更新),它会工作吗?

        4
  •  0
  •   Gary Myers    14 年前

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

    是否涉及数据库链接?

        5
  •  0
  •   Jason Kleban    14 年前

    字段1不是从子查询返回的第一列吗?我怀疑您的in只会将值与结果的第一列进行比较。