Oracle:从其他表中的值更新表a中的列

时间:2010-09-30 10:34:27

标签: sql oracle dml

我正在尝试为我正在编写的应用程序支持多个数据库。该应用程序主要使用Hibernate,但是当DML语句可以在很短的时间内处理它们时,迭代数百万行并单独处理它们是极其低效的。因此,对于某些操作,我需要编写SQL。我更像是一个MySQL人,但到目前为止,我的应用程序正在使用SQL Server和MySQL。有一个操作困扰了我,我似乎无法弄清楚如何为Oracle构建一些更新查询。我知道,就Oracle而言,这可能是一个新手问题,但是当我一直在寻找时,我一定错过了明显的答案....

以下是我为MySQL编写此类查询的方法:

更新table1 t1,table2 t2 set t1.colA = t2.colA其中t1.colB = t2.colB和t1.colC = t2.colC

MySQL有一个很好的构造,你可以在带有别名的'set'语句之前指定所有表,这极大地简化了语句的其余部分。在SQL Server中,我使用update ... join来做同样的事情。

在Oracle中,我尝试使用'update table1 set colA =(select ....)where exists(select ....)语法,但这不起作用 - 它返回'子查询返回更多比一行'错误。我也尝试使用合并...使用...语法,但是错误“无法从源表中获取稳定的行集”。

为了进一步解释我想要实现的目标,我要执行一些查询,其中一些使用2个表,一些使用3个表。最复杂的需要做到这一点:

使用tableC.colC中的值更新tableA.colB,其中tableA.colA = tableB.colA和tableB.colB = tableC.colB用于所有匹配的行。在数据方面,这看起来像这样(之前和之后):

Before:

Table A
-------
colA     colB
1        NULL
2        NULL
3        NULL
4        NULL

Table B
-------
colA     colB
1        A
2        A
3        B
4        B

Table C
-------
colB     colC
A        15
B        20

After:

Table A
-------
colA     colB
1        15
2        15
3        20
4        20

我希望这很清楚。谁能解释如何为Oracle编写这种DML查询?对于奖励积分,PostgreSQL是否相同? :)

3 个答案:

答案 0 :(得分:2)

您可以使用distinct忽略相同值的多个副本:

update  TableA
set     ColB = 
        (
        select  distinct ColC
        from    TableC C
        join    TableB B
        on      C.ColB = B.ColB
        where   B.ColA = TableA.ColA
        )

如果找到多个合适的值,这仍然会出错。

答案 1 :(得分:2)

<强>前

    SQL> select * from A
      2  /

          COLA       COLC
    ---------- ----------
             1
             2
             3
             4

    SQL> select * from B
      2  /

          COLA C
    ---------- -
             1 A
             2 A
             3 B
             4 B

    SQL> select * from C
      2  /

    C       COLC
    - ----------
    A         15
    B         20

    SQL>

查询

    SQL> update A
      2  set colc = ( select c.colc
      3               from c
      4                      join b on ( c.colB = b.colB )
      5               where
      6                  b.colA = A.colA )
      7  where exists
      8      ( select null
      9               from c
     10                      join b on ( c.colB = b.colB )
     11               where
     12                  b.colA = A.colA )
     13  /

    4 rows updated.

    SQL>

<强>后

    SQL> select * from A
      2  /

          COLA       COLC
    ---------- ----------
             1         15
             2         15
             3         20
             4         20

    SQL>

显然,您在测试用例中简化了某些内容,因此它无法代表您的实际情况。关键是,我的查询有效,因为子查询为A.colA的每个值返回一行。您需要重新访问您的数据并建立必要的标准。这是数据/业务逻辑问题,而不是语法问题。

答案 2 :(得分:0)

尝试以下方法:

UPDATE table_a a
  SET col_b = (SELECT col_c
                 FROM table_b b,
                      table_c c
                 WHERE b.col_a = a.col_a AND
                       c.col_b = b.col_b);

我没碰巧在这台机器上安装了Postgresql,所以无法对此发表评论。

分享并享受。