Oracle更新记录的子查询

时间:2014-12-11 11:10:32

标签: oracle

我需要更新子查询给出的记录列表,在网上嗅探我试过这个结构:

UPDATE
  (
    SELECT
      a.COL1
    FROM
      TABLE1 a,
      TABLE2 b
    WHERE
      a.field1 = b.field1
  ) update_tbl
SET
  update_tbl.COL1 = 'VALUE'

但是它返回给我这个Oracle错误:

-> ORA-01779: Cannot modify a column which maps to a non key-preserved table

我的查询如下:

UPDATE 
    (
        SELECT 
            imp.*
        FROM table1 imp
        JOIN table2 sp ON imp.id_p = sp.id_p
        JOIN table3 cs ON sp.id_s = cs.id_s
        JOIN table4 cb ON cb.id_c = cs.id_c
        WHERE
        imp.id_b = cb.id_b
        AND (
                (to_char(imp.p,'yyyymm') < to_char(cb.data_in,'yyyymm')) OR
                (cb.data_fi IS NOT NULL AND to_char(imp.p,'yyyymm') > to_char(cb.data_fi,'yyyymm'))
            )
        and (
                (imp.v is not null) or
                (imp.v_s is not null and imp.v_s <> 0) or
                (imp.imp_co is not null and imp.imp_co <> 0) or
                (imp.imp_acc is not null and imp.imp_acc <> 0) 
                )
    ) i
    SET
        i.v = null,
        i.v_s = 0,
        i.imp_co = 0,
        i.imp_acc = 0,
        i.ID_S_CONT = 'N',
        i.ID_T_COMP = 'P',
        i.date_upd = SYSDATE,
        i.user_upd = 'SeR'

子查询返回82行(现在测试),我确实只想修改那些行,我做错了什么?

1 个答案:

答案 0 :(得分:1)

我认为您正在更新到imp表。所以你可以尝试下面的MERGE

       MERGE INTO 
       IMP A
    USING 
       ( SELECT 
                imp.*
            FROM table1 imp
            JOIN table2 sp ON imp.id_p = sp.id_p
            JOIN table3 cs ON sp.id_s = cs.id_s
            JOIN table4 cb ON cb.id_c = cs.id_c
            WHERE
            imp.id_b = cb.id_b
            AND (
                    (to_char(imp.p,'yyyymm') < to_char(cb.data_in,'yyyymm')) OR
                    (cb.data_fi IS NOT NULL AND to_char(imp.p,'yyyymm') > 
to_char(cb.data_fi,'yyyymm'))
                )
            and (
                    (imp.v is not null) or
                    (imp.v_s is not null and imp.v_s <> 0) or
                    (imp.imp_co is not null and imp.imp_co <> 0) or
                    (imp.imp_acc is not null and imp.imp_acc <> 0) 
                    )) B

    ON (A.ID =B.ID)
    WHEN MATCHED THEN 
    UPDATE SET 
    A.v = null,
            A.v_s = 0,
            A.imp_co = 0,
            A.imp_acc = 0,
            A.ID_S_CONT = 'N',
            A.ID_T_COMP = 'P',
            A.date_upd = SYSDATE,
            A.user_upd = 'SeR'

将更新子查询给出的表。这里A.ID =B.ID使用主键。