Oracle - 是否可以在更新期间在case语句中“设置”值,如下所示?

时间:2015-02-12 17:05:01

标签: oracle

是否可以在更新期间在case语句中“设置”值,如下所示?

UPDATE TABLE1
  CASE WHEN COL1 = 'A' THEN SET COL2 = 10, COL3 = 20, COL4 = 30
       WHEN COL1 IN ('B','N') THEN SET COL2 = 1, COL3 = 5, COL4 = 7
       WHEN COL1 = 'D' THEN SET COL2 = 11, COL3 = 13, COL4 = 17
       ELSE SET COL2 = 0, COL3 = 0, COL4 = 0
  END;

3 个答案:

答案 0 :(得分:7)

相应的有效语法是这样的。

UPDATE TABLE1 SET
  COL2 = (CASE WHEN COL1 = 'A' THEN 10
               WHEN COL1 IN ('B','N') THEN 1
               WHEN COL1 = 'D' THEN 11
               ELSE 0
          END), 
  COL3 = (CASE WHEN COL1 = 'A' THEN 20
               WHEN COL1 IN ('B','N') THEN 5
               WHEN COL1 = 'D' THEN 13
               ELSE 0
          END), 
  COL4 = (CASE WHEN COL1 = 'A' THEN 30
               WHEN COL1 IN ('B','N') THEN 7
               WHEN COL1 = 'D' THEN 17
               ELSE 0
          END);

答案 1 :(得分:2)

要通过case执行此操作,您必须为每个字段重复case(由@MaheswaranRavisankar演示)。这就是case的工作方式。另一种方法是制作提供相同结果的子查询。虽然时间较长,但它会将相关值组合在一起,这可能更易读/更容易维护。

鉴于需要将所有非匹配值设置为零,我将首先通过将所有值设置为零来解决此问题,然后将匹配更新为适当的值。

UPDATE table1
SET    col2 = 0, col3 = 0, col4 = 0;

UPDATE table1
SET    (col2, col3, col4) =
          (SELECT a.col2, a.col3, a.col4
           FROM   (SELECT 'A' AS col1,
                          10 AS col2,
                          20 AS col3,
                          30 AS col4
                   FROM   DUAL
                   UNION ALL
                   SELECT 'B' AS col1,
                          5 AS col2,
                          5 AS col3,
                          7 AS col4
                   FROM   DUAL
                   UNION ALL
                   SELECT 'N' AS col1,
                          5 AS col2,
                          5 AS col3,
                          7 AS col4
                   FROM   DUAL
                   UNION ALL
                   SELECT 'D' AS col1,
                          13 AS col2,
                          7 AS col3,
                          17 AS col4
                   FROM   DUAL) a
           WHERE  a.col1 = table1.col1);

这也暗示了另一种选择:也许您应该考虑使用这些值创建一个表,而不是将它们嵌入到SQL中。

答案 2 :(得分:2)

看起来你正在尝试做一个MERGE,但有一个例外。除了将所有不匹配的行更新为0的逻辑外,您可以在单个合并语句中更新表,如下所示。

SQL> create table tab1
(
col1 varchar2(10),
col2 number,
col3 number,
col4 number,
merge_flag char(1)
)
Table created.
SQL> insert into tab1 values ('A', 10,11,12,null)
1 row created.
SQL> insert into tab1 values ('B', 20,21,22,null)
1 row created.
SQL> insert into tab1 values ('C', 30,31,32,null)
1 row created.
SQL> commit
Commit complete.
SQL> select * from tab1

COL1             COL2       COL3       COL4 MERGE_FLAG
---------- ---------- ---------- ---------- ----------
A                  10         11         12           
B                  20         21         22           
C                  30         31         32           

3 rows selected.
SQL> merge into tab1 t
using (
    select 'A' as col1, 10 as col2, 20 as col3, 30 as col4 from dual
    union
    select 'B' as col1, 1 as col2, 5 as col3, 7 as col4 from dual
    union
    select 'N' as col1, 1 as col2, 5 as col3, 7 as col4 from dual
    union
    select 'D' as col1, 11 as col2, 13 as col3, 17 as col4 from dual
) x
on (t.col1 = x.col1)
when matched then
    update set t.col2 = x.col2, t.col3 = x.col3, t.col4 = x.col4, t.merge_flag = 'X'
Merge successfully completed.
SQL> commit
Commit complete.
SQL> select * from tab1

COL1             COL2       COL3       COL4 MERGE_FLAG
---------- ---------- ---------- ---------- ----------
A                  10         20         30 X         
B                   1          5          7 X         
C                  30         31         32           

3 rows selected.

您可以在合并后运行单个更新,以将所有不匹配的行更改为0.