达梦数据库-集合FORALL的使用方法

假定有两张本地空表        test_tab_main;test_tab_other。

        这些表应使用一下规则从test_5表加载数据:

        1、如果object_type是table,把新行数据加载到test_tab_main中。

        2、所有其他对象都添加到test_tab_other中。

测试的目的:

        以单一的对象集合作为源,再加上次集合里对象所发生的不同动作。这对重要的数据转换活动的数据迁移项目是特别方便的。

        

第一种方式:

create or replace procedure p_testtab_regular is
type table_tt is table of test_5%rowtype;
v_tt table_tt;
v_cur sys_refcursor;

begin
	open v_cur for select * from test_5;
	loop
		fetch v_cur bulk collect into v_tt limit 5000;
		exit when v_tt.count()=0;
		for i in v_tt.first..v_tt.last loop
			if v_tt(i).object_type='TABLE' then
				insert into test_tab_main values v_tt(i);
			else 
				insert into test_tab_other values v_tt(i);
			end if;
		end loop;
		exit when v_tt.count<5000;
	end loop;
	close v_cur;
end;

这种方式不是最佳的。insert 语句每次都被启用,没有效率。

第二种方式:

create or replace procedure  p_testtab_forall is
	type table_tt is table of test_5%rowtype;
	type number_tt is table of binary_integer;
	v_tt table_tt;
	v_cur sys_refcursor;
--第一步
	v_main_tt number_tt;
	v_other_tt number_tt;
begin
	open v_cur for select * from test_5;
	loop
		v_main_tt:=number_tt();
		v_other_tt:=number_tt();
		fetch v_cur bulk collect into v_tt limit 5000;
		exit when v_tt.count()=0;
--第二步
		for i in v_tt.first..v_tt.last loop
			if v_tt(i).object_type='TABLE' then
				v_main_tt.extend;
				v_main_tt(v_main_tt.last):=i;
			else
				v_other_tt.extend;
				v_other_tt(v_other_tt.last):=i;
			end if;
		end loop;
		
--插入数据
		FORALL ind IN v_main_tt.first .. v_main_tt.last
    		INSERT INTO test_tab_main VALUES v_tt(ind);
		FORALL ind IN v_other_tt.first .. v_other_tt.last
    		INSERT INTO test_tab_other VALUES v_tt(ind);
		exit when v_tt.count<5000;
	end loop;
	close v_cur;
end;

        首先,应该添加一个新的集合类型来存储对象的ID。考虑两个对象表,需要两个索引变量,一个表一个。

        第二步涉及与先前第一种方式传递源表的方法相同,但这一过程会记录索引集合中的ID,而不是insert语句。

        第三步是启用insert语句,但不是一次启用一条,而是可以利用forall的语句来启用。v_main_tt和v_other_tt集合的值是v_tt集合的ID

比较两种方式的资源消耗情况:

select sessid; --查询的当前会话&session_id

create table mystat_start as select * from V$sesSTAT where sid = '&session_id';
exec p_testtab_forall;
create table mystat_mid as select * from V$sesSTAT where sid = '&session_id';
exec p_testtab_regular;
create table mystat_stop as select * from V$sesSTAT where sid = '&session_id';


--查看比较
select ss1.id,ss1.name,ss1.stat_val as forall_tab,ss2.stat_val as regular_tab from (
select * from mystat_start
minus
select * from mystat_mid
)ss1
,(
select * from mystat_mid
minus
select * from mystat_stop
)ss2
where ss1.id = ss2.id

https://eco.dameng.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值