Oracle 使用单个select的值更新多个列

Oracle 使用单个select的值更新多个列,oracle,sql-update,Oracle,Sql Update,现在我得到了这样的东西: UPDATE TableA SET a = (SELECT b FROM TableB), aa = (SELECT b FROM TableB) 有更优雅的解决方案吗?您可以写: UPDATE TableA SET (a, aa) = (SELECT b, b FROM TableB); 注意:这假设TableB只包含一行。否则,将引发异常。使用另一个表中的值更新一个表时要小心,否则即使您认为只更新了几行,也会更新目标表中的所有行。在大型表上,这将非常痛

现在我得到了这样的东西:

UPDATE TableA
SET a  = (SELECT b FROM TableB),
    aa = (SELECT b FROM TableB)
有更优雅的解决方案吗?

您可以写:

UPDATE TableA
SET (a, aa) = (SELECT b, b FROM TableB);

注意:这假设TableB只包含一行。否则,将引发异常。

使用另一个表中的值更新一个表时要小心,否则即使您认为只更新了几行,也会更新目标表中的所有行。在大型表上,这将非常痛苦,并且会损坏您的数据。例如:

update tab_x x
set (col2, col3) = (
    select col2, col3
    from tab_y y
    where x.col1 = y.col1)
-- the following part will make sure we only update rows
-- that match the join condition (x.col1 = y.col1)
-- without this part, we'd update all rows in the x table!
where exists (
    select 1
    from tab_y y
    where x.col1 = y.col1
)
完整的例子是:

SQL> set display on
SQL> drop table tab_x
Table dropped.
SQL> create table tab_x
(
col1 number,
col2 varchar2(20),
col3 varchar2(20)
)
Table created.
SQL> drop table tab_y
Table dropped.
SQL> create table tab_y
(
col1 number,
col2 varchar2(20),
col3 varchar2(20)
)
Table created.
SQL> insert into tab_x values (1, 'Col2 from x','Col3 from x')
1 row created.
SQL> insert into tab_x values (2, 'Col2 from x','Col3 from x')
1 row created.
SQL> insert into tab_x values (3, 'Col2 from x','Col3 from x')
1 row created.
SQL> insert into tab_y values (1, 'Col2 from y','Col3 from y')
1 row created.
SQL> insert into tab_y values (2, 'Col2 from y','Col3 from y')
1 row created.
SQL> insert into tab_y values (9, 'Col2 from y','Col3 from y')
1 row created.
SQL> commit
Commit complete.
SQL> select * from tab_x

      COL1 COL2                 COL3                
---------- -------------------- --------------------
         1 Col2 from x          Col3 from x         
         2 Col2 from x          Col3 from x         
         3 Col2 from x          Col3 from x         

3 rows selected.
SQL> update tab_x x
set (col2, col3) = (
    select col2, col3
    from tab_y y
    where x.col1 = y.col1)
-- the following part will make sure we only update rows
-- that match the join condition (x.col1 = y.col1)
-- without this part, we'd update all rows in the x table!
where exists (
    select 1
    from tab_y y
    where x.col1 = y.col1
)
2 rows updated.
SQL> select * from tab_x

      COL1 COL2                 COL3                
---------- -------------------- --------------------
         1 Col2 from y          Col3 from y         
         2 Col2 from y          Col3 from y         
         3 Col2 from x          Col3 from x         

3 rows selected.

它应该是一个相关的子查询吗?是的,还不广为人知。另外值得注意的是,您可以在WHERE子句中使用类似的构造,例如。。。其中a、aa在另一张表格中选择b、bb。