在Oracle中一次对补充数据执行两次UPDATE
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Oracle中一次对补充数据执行两次UPDATE相关的知识,希望对你有一定的参考价值。
我有下表需要更新:
USER:
| ID | ACTIVE | REF_COL | COL_2 | COL_3 |
|----|--------|---------|-------|-------|
| 1 | 1 | value | value | value |
| 2 | 0 | value | value | value |
| 3 | 1 | value | value | value |
我分别执行以下两个UPDATE
语句:
- 声明-1
UPDATE USER SET ACTIVE = 1 WHERE REF_COL IN ( -- Subquery that generates a list of values )
- 声明-2
UPDATE USER SET ACTIVE = 0 WHERE REF_COL NOT IN ( -- Subquery that generates a list of values )
生成值列表的子查询对于两个UPDATE
查询都是相同的。
是否有任何方法可以帮助我立即执行查询,例如MERGE
?
使用MERGE
语句的以下查询无效:
MERGE INTO USER U
USING (
-- Subquery that generates a list of values
) T
ON (U.REF_COL = T.VALUE)
WHEN MATCHED THEN
UPDATE SET U.ACTIVE = 1
WHEN NOT MATCHED THEN
UPDATE SET U.ACTIVE = 0
由于WHEN NOT MATCHED THEN
条款希望有一个INSERT
声明。
答案
这是一个merge
版本的例子。您必须在源部分中放置逻辑:
merge into users tgt
using (
select u.ref_col, nvl2(s.ref_col, 1, 0) active
from users u
left join subquery s on u.ref_col = s.ref_col ) src
on (tgt.ref_col = src.ref_col)
when matched then update set active = src.active;
另一答案
在CASE
中使用SET
UPDATE
USER U
SET
U.ACTIVE = (CASE WHEN U.REF_COL IN (<subquery>) THEN 0 ELSE 1 END)
另一答案
使用Ponder Stibbons在他的answer中提供的想法,我创建了以下查询;我添加的额外逻辑是仅过滤那些需要更新ACTIVE
值的行:
MERGE INTO USER U
USING (
SELECT
TGT.ID,
SRC.ACTIVE
FROM
USER TGT
JOIN (
SELECT
U.REF_COL,
NVL2(T.REF_COL, 1, 0) AS ACTIVE
FROM
USER U
LEFT JOIN (
-- Subquery that generates a list of values
) T ON T.REF_COL = U.REF_COL
) SRC ON TGT.REF_COL = SRC.REF_COL
WHERE
TGT.ACTIVE != SRC.ACTIVE
) F
ON (U.ID = F.ID)
WHEN MATCHED THEN
UPDATE SET
U.ACTIVE = F.ACTIVE
另一答案
合并伪代码:
MERGE into <target table>
USING
<souce table/view/result of subquery>
ON
<match condition>
WHEN MATCHED THEN
<update clause>
<delete clause>
WHEN NOT MATCHED THEN
<insert clause>
oracle docs如下所示:merge_insert_clause指定在ON子句的条件为false时插入目标表的列的值。如果执行insert子句,则激活目标表上定义的所有插入触发器。如果省略INSERT关键字后面的列列表,则目标表中的列数必须与VALUES子句中的值数相匹配。你不能使用合并或两个更新一个匹配和其他不匹配。
你必须创建一个程序。
CREATE OR REPLACE PROCEDURE all_updates_in_user
IS
cursor c1 is<<query that generates a list of values>>
BEGIN
FOR rec in c1
LOOP
UPDATE
USER
SET
ACTIVE = 1
WHERE
REF_COL IN rec.columnname;
UPDATE
USER
SET
ACTIVE = 0
WHERE
REF_COL NOT IN rec.columnname;
END LOOP;
END;
以上是关于在Oracle中一次对补充数据执行两次UPDATE的主要内容,如果未能解决你的问题,请参考以下文章