pl/sql中嵌套表的使用

        在处理计算结果集的应用时,如果仅仅从数据库中获取相应的数据,把业务实现过程放到java代码来实现,对于数据量小的情况也许可以完全应付,只是对于大数据量的业务计算逻辑时,会造成与数据库的频繁交互,消耗不必要的内存资源。针对这些问题,有时候使用缓存能在一定程度上减少对数据库的访问,从而提高程序的应用性能。不过,更好的解决办法应该是在数据层完成这些业务计算,而程序访问数据库时就可以直接将计算结果集获取到,从而大大提高了程序应用性能,减少了很多不必要的内存消耗。

         在项目开发中,我也遇到过类似的问题,后来通过plsql编程,使用嵌套表很顺利地解决了这个问题。下面就简单以oracle的示例来展示嵌套表的应用。

        1. 创建object类型:

create or replace type company_info_record as object(empname varchar2(100),
                                   job varchar2(100),
                                   sal number(10,2),
                                   dname varchar2(100)
                                   );

     2. 创建表类型: 
create or replace type company_info_table is table of company_info_record;




         3. 创建一个包进行封装,包中创建一个procedure,并通过一个游标返回计算结果集。

          3.1)包声明:

               

type cur_back_company_info is ref cursor;

procedure proc_check_company_info(p_tax_rate      in number,
                                  p_cur_back_info out cur_back_company_info);

     
         3.2) 包体:
             
      procedure proc_check_company_info(p_tax_rate      in number,  ----税率,要求每个员工的薪水都是税后的
                                        p_cur_back_info out cur_back_company_info) is
        cursor cur_get_nested_msg is
        
          select d.dname dname, e.ename ename, e.sal sal, e.job job
            from emp e
            left join dept d
              on e.deptno = d.deptno;
      
        v_cur_nested_info cur_get_nested_msg%rowtype;
        v_company_info    company_info_table := company_info_table();
        v_count           number(5);
      
      begin
        v_count := 1;
        open cur_get_nested_msg;
        loop
          fetch cur_get_nested_msg
            into v_cur_nested_info;
          exit when cur_get_nested_msg%notfound;
          if v_cur_nested_info.sal > 0 and p_tax_rate > 0 then
            v_cur_nested_info.sal := round(v_cur_nested_info.sal *
                                           p_tax_rate,
                                           2);
          end if;
        
          v_company_info.extend;
        
          v_company_info(v_count) := company_info_record(v_cur_nested_info.ename,
                                                         v_cur_nested_info.dname,
                                                         v_cur_nested_info.sal,
                                                         v_cur_nested_info.job);
          v_count := v_count + 1;
        end loop;
        close cur_get_nested_msg;
        open p_cur_back_info for
          select * from table(cast(v_company_info as company_info_table));
      exception
        when others then
          raise;
      end proc_check_company_info;



                4.java调用,(如果使用ibatis或hibernate则需要配置)

                 

package com.databaseConnection;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;

import oracle.jdbc.OracleTypes;

/**
 * 
 * @author
 * @date: 2011-3-31上午12:05:14
 */
public class Connector {
	private String url = "jdbc:oracle:thin:@192.168.133.125:1521:orcl";
	private String userName = "scott";
	private String pwd = "tan123";
	private Connection conn = null;

	public Connection connect() {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			try {
				this.conn = DriverManager.getConnection(this.url,
						this.userName, this.pwd);
				String sql="{call scott_test_pkg.proc_check_company_info(?,?)}";//"{call scott_test_pkg.proc_sp_pro9(?,?)}";
				CallableStatement callStatement=conn.prepareCall(sql);
				//callStatement.setInt(1, 10);
				callStatement.setFloat(1, Float.parseFloat("0.96"));
				callStatement.registerOutParameter(2, OracleTypes.CURSOR);
				callStatement.execute();
				ResultSet set=(ResultSet)callStatement.getObject(2);
				while(set.next()){
					//System.out.println(set.getInt(1)+" "+set.getString(2)+" "+set.getString(3)+" ");
					System.out.println(set.getString(1)+" "+set.getString(2)+" "+set.getDouble(3)+" "+set.getString(4));
				}
				callStatement.close();
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} catch (Exception exception) {
			exception.printStackTrace();
		}
		return this.conn;
	}
}
                5.main方法调用输出:

        

package com.databaseConnection;


public class DbConnectionApp 
{
    public static void main( String[] args )
    {
    	
    	Connector connector=new Connector();
    	connector.connect();
    }
}
        6.输出结果:

           

MILLER ACCOUNTING 1248.0 CLERK
KING ACCOUNTING 4800.0 PRESIDENT
CLARK ACCOUNTING 2352.0 MANAGER
FORD RESEARCH 2880.0 ANALYST
ADAMS RESEARCH 1056.0 CLERK
SCOTT RESEARCH 2880.0 ANALYST
JONES RESEARCH 2856.0 MANAGER
SMITH RESEARCH 768.0 CLERK
JAMES SALES 912.0 CLERK
TURNER SALES 1440.0 SALESMAN
BLAKE SALES 2736.0 MANAGER
MARTIN SALES 1200.0 SALESMAN
WARD SALES 1200.0 SALESMAN
ALLEN SALES 1536.0 SALESMAN

     总结:

          在实际的项目开发中,plsql编程其实是可以让我们减少很多业务上处理上的烦恼,其中像嵌套表、record等可以很方便地解决我们业务上的困难,尤其是在大数据量的计算时,如果使用java来处理这些工作,将会很繁琐且性能低下的选择。

         以上仅是简单案例,如有不足,请提出,愿与大家共同学习。





  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tanrenzong1986

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值