一次更新多个列(变体)

时间:2016-07-28 22:13:28

标签: sql oracle multiple-columns database-link

我正在尝试更新Oracle中的多个列,并在完成以下代码的几个方案之后。

我的问题是更简化的代码没有更新我需要的东西,而更复杂的代码 - 我试图通过最小的处理能力实现这一点,因为我正在看数十万个更新甚至更多。

所以第一个代码:

UPDATE table@database1 i2 
SET    (i2.access, i2.permission) = 
(select 
i2m.access, i2m.permission 
from temporarytable ss
    JOIN table2 pgm 
     ON ss.secgroup = pgm.string 
   JOIN table i2m 
     ON pgm.hmy = i2m.hgroup 
        AND ss.pername = i2m.sobjname 
   JOIN table2@database1 pg 
     ON ss.secgroup = pg.string 

    WHERE 
    pg.string = 'string'  -- this limits the updates to a specific subset of data
    and i2m.hmy > 0 -- this for some freak records in both tables that are missing a primary key
    and pg.hmy = i2.hgroup -- this matches the key of the 'string' from above to the records i need to update
    and ss.pername = i2.sobjname -- further condition on which records to update. so only the ones that match from the temp table to the target table
    and ss.orig_hmy = i2.hmy) -- further condition to make sure i am updating only records matching between temp table and target table

现在,如果我运行它,而不是只更新大约700条与上述子查询匹配的记录,它会更新表'table @ database1'中的所有记录,我看不清楚为什么(可能是我不喜欢的那些东西之一)得到甲骨文:))

但是如果我运行下面的 - 唯一的区别是我将整个子查询插入'where exists' - 那么这只会更新我需要的内容。我的问题是我理解它的方式,子查询运行两次 - 一次在更新中,一次在where子句中 - 我会说这是浪费处理能力。

UPDATE table@database1 i2 
SET    (i2.access, i2.permission) = 
(select 
i2m.access, i2m.permission 
from temporarytable ss
    JOIN table2 pgm 
     ON ss.secgroup = pgm.string 
   JOIN table i2m 
     ON pgm.hmy = i2m.hgroup 
        AND ss.pername = i2m.sobjname 
   JOIN table2@database1 pg 
     ON ss.secgroup = pg.string 

    WHERE 
    pg.string = 'string'
    and i2m.hmy > 0
    and pg.hmy = i2.hgroup
    and ss.pername = i2.sobjname
    and ss.orig_hmy = i2.hmy)

where exists (select 
i2m.access, i2m.permission 
from temporarytable ss
    JOIN table2 pgm 
     ON ss.secgroup = pgm.string 
   JOIN table i2m 
     ON pgm.hmy = i2m.hgroup 
        AND ss.pername = i2m.sobjname 
   JOIN table2@database1 pg 
     ON ss.secgroup = pg.string 

    WHERE 
    pg.string = 'string'
    and i2m.hmy > 0
    and pg.hmy = i2.hgroup
    and ss.pername = i2.sobjname
    and ss.orig_hmy = i2.hmy)

注意:如果它没有显示,我有多个具有相同模式的DB。我正在尝试使用主模式中的信息更新数据库中的表。 Temp表充当不同记录并需要更新的存储库 - 如果只有15%与主模式不同,则没有理由更新数百万条记录。

1 个答案:

答案 0 :(得分:1)

在从这里的所有乐于助人的人那里得到建议之后,我调查了使用MERGE并将以上查询改编成以下内容 - 事实证明这是成功的!

    MERGE INTO table@database1 i2 
    USING (
    select i2m.access, i2m.permission, ss.orig_hmy
    from table i2m
        JOIN table2 pgm 
         ON i2m.hgroup = pgm.hmy 
       JOIN temporarytable ss
         ON pgm.string = ss.string 
            AND ss.pername = i2m.sobjname 
       JOIN table2@database1 pg 
         ON ss.string = pg.string 
    WHERE 1 = 1
        and i2m.hmy > 0 
        and pg.string = 'string'
        and ss.database = 'database1' 
    ) u on (i2.hmy = u.orig_hmy)
    WHEN MATCHED THEN
        UPDATE SET i2.access = u.access, i2.permission = u.permission;

非常感谢所有人!