【问题标题】:Oracle SQL: Conditionally update a table based on comparison with a SQL statementOracle SQL:根据与 SQL 语句的比较有条件地更新表
【发布时间】:2012-06-04 17:09:36
【问题描述】:

我有一个有 4 列的表 (TABLE1):

UID | PID |价值1 | VALUE2

我有另一个 SQL 语句 (STMT),它从其他一些表中返回 3 列:

UID | PID | VALUE1

现在这里是我想要更新 TABLE1 的条件:

首先,将 STMT 中的 UID 和 PID 对与 TABLE1 中的进行比较,

  1. 对于不在 TABLE1 中的所有新 UID 和 PID 对,将 STMT 中的新行插入到 TABLE1 中,设置 TABLE1.VALUE2 = 0(我已经这样做了)

  2. 对于 STMT 和 TABLE1 中现有的 UID 和 PID 对,请执行以下操作:

    一个。如果 TABLE1.VALUE2 > 0,则更新 TABLE1.VALUE1 = STMT.VALUE1

    b.如果 TABLE1.VALUE2 = 0 并且如果 TABLE1.VALUE1 != STMT.VALUE1,则更新 TABLE1.VALUE1 = STMT.VALUE1,否则什么也不做。

我无法为条件 2 提出解决方案。感谢您的帮助!

【问题讨论】:

  • 第2步之后的最终结果是table1.value1 = stmt.value 1的所有情况。您是否特别需要避免将行更新为它们已经存在的相同值,以便触发器不会触发?
  • @evilotto 没关系,最终目的是让 TABLE1 始终保持最新。

标签: sql oracle


【解决方案1】:
UPDATE (
    SELECT table1.UID
           ,table1.PID
           ,table1.value1 AS table1_value1
           ,table1.value2 AS table1_value2
           ,stmt.value1 AS stmt_value1
    FROM table1
    INNER JOIN (SELECT ? AS UID
                       ,? AS PID
                       ,? AS value1
                FROM whatever) stmt
        ON stmt.UID = table1.UID
        AND stmt.PID = table1.PID
) x
SET x.table1_VALUE1 = CASE WHEN (x.table1_VALUE2 > 0) OR
                              (x.table1_VALUE2 = 0 AND x.table1_VALUE1 <> x.stmt_VALUE1)
                              THEN x.stmt_VALUE1
                         ELSE x.table1_VALUE1 
                    END

【讨论】:

  • 感谢您的回答,但我有一个可能很愚蠢的问题:如何将 sql 语句转换为 STMT,以便在更新语句中将其用作 STMT.value1?
  • 再次感谢您的帮助。我现在收到“ORA-01779:无法修改映射到非键保留表的列”错误。知道为什么会这样吗?
  • @AlanHan 只是甲骨文很难。我可以很简单,只需将 table1.UID 和 table1.PID 添加到 x 子查询以获取密钥。否则重构查询以通过组合删除内部子查询,或者改用 MERGE INTO 技术。
【解决方案2】:


您可以使用以下查询

MERGE INTO TABLE1 T
USING STMT S
ON (T.UID  = S.UID AND T.PID = S.PID)
WHEN MATCHED THEN
UPDATE
SET
T.VALUE1 = CASE WHEN T.VALUE2 > 0 OR (T.VALUE2 = 0 AND T.VALUE1 <> S.VALUE1) THEN S.VALUE1 END
WHEN NOT MATCHED THEN
INSERT INTO T (COLUMNS) (SELECT COLUMNS FROM S);

【讨论】:

    猜你喜欢
    • 2017-09-14
    • 1970-01-01
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多