一次更新多个列(变体)
updating multiple columns at once (variation)
我正在尝试更新 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 'table@database1' 中的所有记录,我不明白为什么(可能是我不了解 Oracle 的事情之一 :))
但是如果我 运行 下面 - 唯一的区别是我将整个子查询插入 '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)
注意:如果它没有显示,我有多个具有相同架构的数据库。我正在尝试使用来自主模式的信息跨数据库更新 table。 Temp table 充当不同且需要更新的记录的存储库 - 如果只有 15% 与主模式不同,则没有理由更新数百万条记录。
在听取了这里所有乐于助人的人的建议后,我研究了使用 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;
非常感谢大家!
我正在尝试更新 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 'table@database1' 中的所有记录,我不明白为什么(可能是我不了解 Oracle 的事情之一 :))
但是如果我 运行 下面 - 唯一的区别是我将整个子查询插入 '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)
注意:如果它没有显示,我有多个具有相同架构的数据库。我正在尝试使用来自主模式的信息跨数据库更新 table。 Temp table 充当不同且需要更新的记录的存储库 - 如果只有 15% 与主模式不同,则没有理由更新数百万条记录。
在听取了这里所有乐于助人的人的建议后,我研究了使用 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;
非常感谢大家!