达梦数据库-用PLSQL合并集合

        简单地加载、卸载集合外,对它们进行操作也是非常必要。考虑到很长一段时间以来,SQL开发一直包含UNION/INTERSECT/MINUS子句,通过用户定义的集合来进行类似的操作。

        MULTISET命令为性能调优提供了可能性。

案例背景:

        常常会遇到对一张表,筛选不同类别用户,通过union的方式合并查询结果。随着应用模块上线,产品功能模块增加,从最初只有4个union最终变成14个union。以此往复,安全结构变得更加复杂,不同子查询的过滤条件开始以奇怪的方式叠加。

        

测试案例:

        #如果用户是总经办,查询返回自己的相关信息;如果用户是人事,查询返回除自己以外其他员工的相关信息。

        #如果用户是总经办或者行政,查询返回其他部门员工的相关信息。

        满足以上两个条件的人员列表可以重叠。由于这个原因,需要由 MULTISET UNION DISTINCT 在最后把一起都合并在一起。

过程测试:

1、创建查询输出格式:

        假设需要根据员工姓名,员工ID,员工身份过滤员工。

create type emp_search_ot as object (empno_nr number,
                                    empno_dsp varchar2(256),
                                    comp_nr number);
 
create type emp_search_nt is table of emp_search_ot;

2、创建函数:

create or replace FUNCTION f_attention_ot(i_empno number) RETURN emp_search_nt IS
	v_emp_rec DMHR.EMPLOYEE%ROWTYPE;
	v_out_nt emp_search_nt:=emp_search_nt();
	v_sub_nt emp_search_nt:=emp_search_nt();
	v_comm_nt emp_search_nt:=emp_search_nt();
BEGIN	
	--load information about the logged user
	select * into v_emp_rec from DMHR.EMPLOYEE  where EMPLOYEE_ID=i_empno; 
	--get subordinates
	if v_emp_rec.job_id = '11' then --总经办,查看自己信息
		select emp_search_ot(
			dmhr.employee.employee_id,
			dmhr.employee.employee_name||'('||dmhr.employee.job_id||')',
			dmhr.employee.salary+nvl(dmhr.employee.commission_pct,0))
		BULK COLLECT INTO v_sub_nt
		from DMHR.EMPLOYEE 
		where EMPLOYEE_ID=i_empno;
	ELSEIF v_emp_rec.job_id = '72' then --人事,查看除自己以外的信息
		select emp_search_ot(
			dmhr.employee.employee_id,
			dmhr.employee.employee_name||'('||dmhr.employee.job_id||')',
			dmhr.employee.salary+nvl(dmhr.employee.commission_pct,0))
		BULK COLLECT INTO v_sub_nt
		FROM DMHR.EMPLOYEE 
		where EMPLOYEE_ID!=i_empno;
	end if;
	
	if v_emp_rec.job_id in ('11','22') then  --总经办和行政,查看其它部门的信息
		select emp_search_ot(
			dmhr.employee.employee_id,
			dmhr.employee.employee_name||'('||dmhr.employee.job_id||')',
			dmhr.employee.salary+nvl(dmhr.employee.commission_pct,0))
		BULK COLLECT INTO v_comm_nt
		FROM DMHR.EMPLOYEE 
		where DEPARTMENT_ID != v_emp_rec.DEPARTMENT_ID;
	end if;
	--merge information
	dbms_output.put_line('Merging: '||v_sub_nt.count||'+'||v_comm_nt.count);
	v_out_nt:=v_sub_nt MULTISET UNION DISTINCT v_comm_nt;
	RETURN v_out_nt;
end;

3、结果测试:

select * from table(f_attention_ot(7001));--总经办
select * from table(f_attention_ot(7448));--人事
select * from table(f_attention_ot(7109));--行政

        结果没有什么特别,但所提出的方法清晰地分离了检查当前用户的特权和处理每个条件的核心步骤。Merging输出证明两个集合为了输出而合并在一起。

达梦数据库 - 新一代大型通用关系型数据库 | 达梦在线服务平台

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值