使用返回多行的子查询更新行

时间:2009-07-30 05:11:20

标签: sql oracle

我在使用子查询更新表时遇到错误,该子查询不应该有多个值,但确实如此。

查询:

UPDATE @Table1 SET D = t2.D + t3.D 
FROM @Table1 t1 
INNER JOIN @Table2 t2 ON 
    t1.P = t2.P 
INNER JOIN @Table3 t3 ON 
    t1.A = t3.A

3 个答案:

答案 0 :(得分:2)

在Oracle上,您可以在括号中包含仅返回一行(标量子查询)的查询,并像使用变量/列一样使用它们:

UPDATE Table1 t1
SET D = (SELECT t2.D + t3.D 
         FROM Table2 t2
             ,Table3 t3
         WHERE t1.P = t2.P 
           AND t1.A = t3.A);

如果子查询返回多行,您可能希望在子查询中使用SUM()。 编辑:如果不在子查询中连接表,则应该使用两个子查询。

UPDATE Table1 t1
SET D = (SELECT sum(t2.D) 
         FROM Table2 t2
         WHERE t1.P = t2.P)
        +
        (SELECT sum(t3.D)
         FROM Table3 t3
         WHEREt1.A = t3.A)

答案 1 :(得分:0)

我不了解Oracle,但我知道在SQL-Server中你不能将表名作为参数传递,除非你愿意动态构建一个SQL字符串和EXEC()它。

希望Oracle用户可以确认Oracle是否可以做类似的事情。

答案 2 :(得分:0)

你应该在UPDATE子句中使用@ Table1的别名 - 这甚至可能是你的问题。像这样:

UPDATE t1 SET D = t2.D + t3.D 
FROM @Table1 t1 
INNER JOIN @Table2 t2 ON 
    t1.P = t2.P 
INNER JOIN @Table3 t3 ON 
    t1.A = t3.A

这将更加稳定,因为它会意识到你并没有将它视为FROM子句中的单独表。

事实上,当你有一个FROM子句时,只在UPDATE子句中使用别名是一种很好的做法。

罗布