我正在尝试为我正在编写的应用程序支持多个数据库。该应用程序主要使用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是否相同? :)
答案 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,所以无法对此发表评论。
分享并享受。