2010-09-30 98 views
1

我正试图为我正在编写的应用程序支持多个数据库。该应用程序主要使用Hibernate,但是当DML语句可以在很短的时间内处理它们时,迭代数百万行并单独处理它们的效率非常低。因此,对于某些操作,我需要制定SQL。我更像是一名MySQL人员,但迄今为止我的应用程序可以与SQL Server和MySQL一起工作。有一个操作让我难堪,我似乎无法弄清楚如何为Oracle构建一些更新查询。我知道,这可能是Oracle的一个新手问题,但我一直在寻找时错过了明显的答案......Oracle:通过其他表中的值更新表a中的列

下面是我如何为MySQL编写这种类型的查询:

更新table1的T1,T2表2设定t1.colA = t2.colA其中t1.colB = t2.colB和t1.colC = t2.colC

MySQL有一个很好的结构在那里你可以指定所有表在带有别名的'set'语句之前,这大大简化了声明的其余部分。在SQL Server中,我使用update ... join来做同样的事情。我试过使用'update table1 set colA =(select ....)where exists(select ....)syntax,但这不起作用 - 它返回一个'subquery returns多行'错误。我也尝试在句法上使用merge ... using ...,但是'无法从源表中获取稳定的一组行'的错误。

为了进一步解释我想要实现的目标,我有许多查询要执行,其中一些使用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会一样吗? :)

回答

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 
     ) 

如果不止一个合适的值,发现这仍然给出了一个错误。

+0

是的,这不是我所追求的,因为子查询*将返回多于一行。我不想为每个不同的TableC.colC值运行更新。在Oracle和SQL Server中,我可以在单个DML操作中实现此目的。我想我说'更新TableA设置colB = TableC.colB *为每个案件*其中tableA.colA = tableB.colA和tableB.colB = tableC.colA'。 – 2010-09-30 10:57:25

+0

@Mick Sear:子查询针对TableA中的每一行运行。如果它返回多个值,应该选择哪一个更新ColB? – Andomar 2010-09-30 11:01:46

+0

好吧,我现在看到它,独立运行子查询后。非常感谢 – 2010-09-30 11:32:57

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的值返回一行。您需要重新访问您的数据并确定必要的标准。这是一个数据/业务逻辑问题,而不是语法问题。

+0

正确。感谢您的回复。它现在通过在子选择中使用'distinct'来解决,按照andomar的响应,等待进一步测试 – 2010-09-30 11:37:30

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的这台机器上所以不能对此发表评论。

分享和享受。

+0

是的,我在实际中一直在尝试。这个问题很明显与我的数据。通过Andomar的帮助解决。 – 2010-09-30 11:38:46

相关问题