2012年3月5日星期一
Oracle merge usage
CREATE OR REPLACE PACKAGE etl AS
c_inserting CONSTANT PLS_INTEGER := 0;
c_updating CONSTANT PLS_INTEGER := 1;
FUNCTION merge_counter (
action_in IN PLS_INTEGER DEFAULT c_inserting
) RETURN PLS_INTEGER;
FUNCTION get_merge_update_count RETURN PLS_INTEGER;
FUNCTION get_merge_update_count (
merge_count_in IN PLS_INTEGER
) RETURN PLS_INTEGER;
FUNCTION get_merge_insert_count RETURN PLS_INTEGER;
FUNCTION get_merge_insert_count (
merge_count_in in PLS_INTEGER
) RETURN PLS_INTEGER;
PROCEDURE reset_counters;
END etl;
/
CREATE OR REPLACE PACKAGE BODY etl AS
g_update_counter PLS_INTEGER NOT NULL := 0;
g_insert_counter PLS_INTEGER NOT NULL := 0;
/*-------------- START OF FUNCTION merge_counter --------------------*/
FUNCTION merge_counter (
action_in IN PLS_INTEGER DEFAULT c_inserting
) RETURN PLS_INTEGER IS
BEGIN
CASE action_in
WHEN c_updating
THEN g_update_counter := g_update_counter + 1;
WHEN c_inserting
THEN g_insert_counter := g_insert_counter + 1;
ELSE
RAISE PROGRAM_ERROR;
END CASE;
RETURN 0;
END merge_counter;
/*----------- START OF FUNCTION get_merge_update_count V1 ---------------*/
FUNCTION get_merge_update_count
RETURN PLS_INTEGER is
BEGIN
RETURN g_update_counter;
END get_merge_update_count;
/*----------- START OF FUNCTION get_merge_update_count V2 ---------------*/
FUNCTION get_merge_update_count (
merge_count_in IN PLS_INTEGER
) RETURN PLS_INTEGER IS
BEGIN
RETURN NVL( merge_count_in - g_insert_counter, 0 );
END get_merge_update_count;
/*----------- START OF FUNCTION get_merge_insert_count V1 ---------------*/
FUNCTION get_merge_insert_count
RETURN PLS_INTEGER IS
BEGIN
RETURN g_insert_counter;
END get_merge_insert_count;
/*----------- START OF FUNCTION get_merge_insert_count V2 ---------------*/
FUNCTION get_merge_insert_count (
merge_count_in IN PLS_INTEGER
) RETURN PLS_INTEGER IS
BEGIN
RETURN NVL( merge_count_in - g_update_counter, 0 );
END get_merge_insert_count;
/*-------------- START OF FUNCTION reset_counters --------------------*/
PROCEDURE reset_counters IS
BEGIN
g_update_counter := 0;
g_insert_counter := 0;
END reset_counters;
END etl;
/
2. 创建一个验证的sql文件:run_mrg.sql
SQL code
set serverout on
set echo on
set pagesize 100
--
-- Run merge...
--
begin
etl.reset_counters;
merge into target tgt
using source src
on (src.id = tgt.id)
when matched then
update
set value = (case etl.merge_counter(etl.c_updating)
when 0
then src.value
end)
when not matched then
insert
( tgt.id
, tgt.value )
values
( case etl.merge_counter(etl.c_inserting)
when 0
then src.id
end
, src.value );
/* Use update count... */
dbms_output.put_line(sql%rowcount || ' rows merged.');
dbms_output.put_line(etl.get_merge_update_count || ' rows updated.');
dbms_output.put_line(etl.get_merge_insert_count(sql%rowcount) || ' rows inserted.');
/* Use insert count... */
dbms_output.put_line(etl.get_merge_update_count(sql%rowcount) || ' rows updated.');
dbms_output.put_line(etl.get_merge_insert_count || ' rows inserted.');
end;
/
3. 验证上述用法:
create table source ( id int, value varchar2(1) );
create table target ( id int, value varchar2(1) );
insert into source select rownum, substr(object_type,1,1) from user_objects where rownum <= 15;
insert into target select * from source where rownum <= 10;
commit;
运行结果如下:
SQL> insert into source select rownum, substr(object_type,1,1) from user_objects where rownum <= 15;
已创建11行。
SQL> insert into target select * from source where rownum <= 10;
已创建10行。
SQL> commit;
提交完成。
SQL> @E:\MyDocument\notes\oracle_run_merge.sql
SQL> set serverout on
SQL> set echo on
SQL> set pagesize 100
SQL> --
SQL> -- Run merge...
SQL> --
SQL> begin
2
3 etl.reset_counters;
4
5 merge into target tgt
6 using source src
7 on (src.id = tgt.id)
8 when matched then
9 update
10 set value = (case etl.merge_counter(etl.c_updating)
11 when 0
12 then src.value
13 end)
14 when not matched then
15 insert
16 ( tgt.id
17 , tgt.value )
18 values
19 ( case etl.merge_counter(etl.c_inserting)
20 when 0
21 then src.id
22 end
23 , src.value );
24
25 /* Use update count... */
26 dbms_output.put_line(sql%rowcount || ' rows merged.');
27 dbms_output.put_line(etl.get_merge_update_count || ' rows updated.');
28 dbms_output.put_line(etl.get_merge_insert_count(sql%rowcount) || ' rows inserted.');
29
30 /* Use insert count... */
31 dbms_output.put_line(etl.get_merge_update_count(sql%rowcount) || ' rows updated.');
32 dbms_output.put_line(etl.get_merge_insert_count || ' rows inserted.');
33
34 end;
35 /
22 rows merged.
20 rows updated.
2 rows inserted.
20 rows updated.
2 rows inserted.
PL/SQL 过程已成功完成。
SQL>
上述过程我是从asktom上整理出来的。希望对你有所帮助。
merge本身是不带有updated和inserted的详细信息的。
订阅:
博文评论 (Atom)
没有评论:
发表评论