我有一个存储过程,它从几个表中获取数据并创建一个只包含我想要的列的新表。我现在想通过仅尝试插入/更新具有至少一列新数据的行来提高性能。对于只接收已有数据的现有行,我想完全跳过该行的更新。
例如,如果一行包含数据:
ID | date | population | gdp
15 | 01-JUN-10 | 1,530,000 | $67,000,000,000
并且合并声明来自ID 15和日期01-JUN-10,人口1,530,000和gdp $ 67,000,000,000然后我不想更新该行。
以下是我的代码的一些片段:
create or replace PROCEDURE COUNTRY (
fromDate IN DATE,
toDate IN DATE,
filterDown IN INT,
chunkSize IN INT
) AS
--cursor
cursor cc is
select c.id, cd.population_total_count, cd.evaluation_date, cf.gdp_total_dollars
from countries c
join country_demographics cd on c.id = cd.country_id
join country_financials cf on cd.country_id = cf.country_id and cf.evaluation_date = cd.evaluation_date
where cd.evaluation_date > fromDate and cd.evaluation_date < toDate
order by c.id,cd.evaluation_date;
--table
type cc_table is table of cc%rowtype;
c_table cc_table;
BEGIN
open cc;
loop -- cc loop
fetch cc bulk collect into c_table limit chunkSize; --limit by chunkSize parameter
forall j in 1..c_table.count
merge
into F_AMB_COUNTRY_INFO_16830 tgt
using (
select c_table(j).id cid,
c_table(j).evaluation_date eval_date,
c_table(j).population_total_count pop,
c_table(j).gdp_total_dollars gdp
from dual
) src
on ( cid = tgt.country_id AND eval_date = tgt.evaluation_date )
when matched then
update
set tgt.population_total_count = pop,
tgt.gdp_total_dollars = gdp
when not matched then
insert (
tgt.country_id,
tgt.evaluation_date,
tgt.population_total_count,
tgt.gdp_total_dollars )
values (
cid,
eval_date,
pop,
gdp );
exit when c_table.count = 0; --quit condition for cc loop
end loop; --end cc loop
close cc;
EXCEPTION
when ACCESS_INTO_NULL then -- catch error when table does not exist
dbms_output.put_line('Error ' || SQLCODE || ': ' || SQLERRM);
END ;
我在想on
声明,我只能说出一些话:
on ( cid = tgt.country_id AND eval_date = tgt.evaluation_date
AND pop != tgt.population_total_count AND gdp != tgt.gdp_total_dollars )
但肯定有更干净/更有效的方法吗?
答案 0 :(得分:1)
另外,你可以使用ora_hash来获取行的哈希值。所以你的where子句可能就像。
其中ora_hash(src.col1 || src.col2 || src.col3 || src.col4)= ora_hash(src.col1 || src.col2 || src.col3 || src.col4)