Oracle SQL:基于与SQL语句的比较有条件地更新表

Oracle SQL:基于与SQL语句的比较有条件地更新表,sql,oracle,Sql,Oracle,我有一个表TABLE1,它有4列: UID | PID |值1 |值2 我有另一个SQL语句STMT,它从其他一些表返回3列: UID | PID |值1 下面是我想如何更新表1的条件: 首先,将STMT中的UID和PID对与表1中的UID和PID对进行比较 对于不在表1中的所有新UID和PID对,将新行从STMT插入到表1中,设置TABLE1.VALUE2=0我已经完成了这一步 对于STMT和表1中的现有UID和PID对,请执行以下操作: a。如果TABLE1.VALUE2>0,则更新TABL

我有一个表TABLE1,它有4列:

UID | PID |值1 |值2

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

UID | PID |值1

下面是我想如何更新表1的条件:

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

对于不在表1中的所有新UID和PID对,将新行从STMT插入到表1中,设置TABLE1.VALUE2=0我已经完成了这一步

对于STMT和表1中的现有UID和PID对,请执行以下操作:

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

b。如果TABLE1.VALUE2=0,如果TABLE1.VALUE1!=STMT.VALUE1,更新TABLE1.VALUE1=STMT.VALUE1,否则不执行任何操作

我想不出解决第二种情况的办法。感谢您的帮助

您可以使用下面的查询

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
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);

步骤2之后的最终结果是table1.value1的所有案例都=stmt.value1。您是否特别需要避免将行更新为已存在的相同值,以便触发器不会触发?@eviotto很好,最终目的是使表1始终处于最新状态。谢谢您的回答,然而,我有一个可能很愚蠢的问题:如何将sql语句强制转换为STMT,以便在update语句中将其用作STMT.value1?再次感谢您的帮助。我现在得到ORA-01779:无法修改映射到非键保留表错误的列。知道为什么会这样吗?@AlanHan只是觉得很难。我可以简单地将table1.UID和table1.PID添加到x子查询以获取键。否则,重构查询,通过组合内部子查询或使用合并到技术来删除内部子查询。