JAVA EE 之 jdbc调用oracle存储过程实现

本来标题是想想用使用oracle的心得体会的,不过想想自己也没什么体会,只是单纯的按照经理的要求用存储过程所以只是记录下哈哈。

项目是个比较小的项目。是地市的移动公司 管理,统计他们客户使用移动的产品像(宽带、固话、专线)情况以及这方面收入的情况。

需求是:开始他会把他们的客户集团去年十二个月的集团编码、月收入信息导入到系统中显示。然后当前年每月导入上月的所有集团的收入情况。一下举例说明:

这里只导入了 14月份的(应该是18月份的)

需求是要计算收入的保有率和增长金额。(集团数有一万条左右、)

保有率比如今年5月份的保有率就是当前2013 1到四月份的收入和/去年20121月到4月的收入和.

5月份的增长金额就是就是当前2013 1到四月份的收入和减去去年20121月到4月的收入和.

 

我是这样写存储过程的:

create or replace procedurep_srbylAndZzjeAdd(customerCodein in varchar2,p_cursor outtestpackage.test_cursor) is

begin

if(customerCodein='' or customerCodein isnull) then

  open p_cursor for

 select a.customerCode,a.monthlyIncomeSum-b.focusMonthlyIncomeSumzzje,a.monthlyIncomeSum/b.focusMonthlyIncomeSum srbyl   from

 (select customerCode,sum(monthlyIncome) monthlyIncomeSum 

 from t_customer_monthlyincome where monthlyDate<to_char(sysdate,'yyyy-MM') group by customerCode)

  ajoin 

 (select customerCode,sum(focusMonthlyIncome) focusMonthlyIncomeSum fromt_customer_focusmonthlyincome 

 where focusMonthlyDate<to_char(add_months(trunc(sysdate),-12),'yyyy-MM')group by customerCode)b 

  ona.customerCode=b.customerCode;

else

 open p_cursor for

 select a.customerCode,a.monthlyIncomeSum-b.focusMonthlyIncomeSumzzje,a.monthlyIncomeSum/b.focusMonthlyIncomeSum srbyl   from

 (select customerCode,sum(monthlyIncome) monthlyIncomeSum 

 from t_customer_monthlyincome where monthlyDate<to_char(sysdate,'yyyy-MM') group by customerCode)

  ajoin 

 (select customerCode,sum(focusMonthlyIncome) focusMonthlyIncomeSum from t_customer_focusmonthlyincome

 wherefocusMonthlyDate<to_char(add_months(trunc(sysdate),-12),'yyyy-MM') group bycustomerCode)b 

  ona.customerCode=b.customerCode where a.customerCode=customerCodein;

  endif;

end p_srbylAndZzjeAdd;

这是带输入和输出参数(游标类型)的存储过程输入是集团编码(不传入则显示所有的集团列表的保有率和增长金额传入则是计算指定集团编码的数据)因为要列表显示所以输出时用游标类型的类型。

t_customer_monthlyincome是今年的每月收入表t_customer_focusmonthlyincome是去年的12个月的收入表

 oracle里面调用测试:

oracle里面调用要这样写

set serveroutput on;

declare 

type cursor1 is ref cursor;

jslCursor cursor1;

customerCode varchar2(20);

type jsRecord is record(

    customerCode varchar2(20),

    bul number,

    zzje number

);

jslRecord jsRecord;

 

begin

customerCode:='5515672862';

jslCursor:=null;

p_srbylAndZzjeAdd(customerCode,jslCursor);

loop

         fetch jslCursor intojslRecord;

         exit when jslCursor%notfound;

         dbms_output.put_line(jslRecord.customerCode||'   '||jslRecord.zzje);

 endloop;

commit;

end;

jdbc里面调用:

conn = dataSource1.getConnection();//只要能拿到conn 就行了

              CallableStatement cs=null;

              List<Customer> customers=newArrayList<Customer>();

              try {

                     cs= conn.prepareCall("{call p_srbylAndZzjeAdd(?,?)}");

                     cs.setString(1,customerCode);

                     cs.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR);

                     cs.execute();

                     ResultSetresultSet=(ResultSet)cs.getObject(2);

                     

                     while(resultSet.next()) {

                            Customer customer=new Customer();

                            customer.setCustomerCode(resultSet.getString(1));

                            customer.setZzje(resultSet.getString(2));

                            customer.setSrbyl(resultSet.getString(3));

                            customers.add(customer);

                     }

              } catch (SQLException e) {

                     e.printStackTrace();

              }finally{

                     if(cs!=null){

                            try {

                                   cs.close();

                            } catch (SQLException e) {

                                   e.printStackTrace();

                            }

                     }

                     if(conn!= null){

                            try {

                                   if(!conn.isClosed()){

                                          conn.close();

                                   }

                            } catch (SQLException e) {

                                   e.printStackTrace();

                            }

                     }

              }

              return customers;

也可以这样:即是把计算出来的结果插入到另一张表里面(用oracle job执行这个存储过程)然后用简单的select查询就可以了。

create or replace procedure p_srbylAndZzjeis

type p_cursor1 is ref cursor;

p_cursor p_cursor1;

type jsRecord is record(

    customerCode varchar2(20),

    byl number,

    zzje number

);

jslRecord jsRecord;

begin

 

 open p_cursor for

 select a.customerCode,a.monthlyIncomeSum-b.focusMonthlyIncomeSumzzje,a.monthlyIncomeSum/b.focusMonthlyIncomeSum srbyl   from

 (select customerCode,sum(monthlyIncome) monthlyIncomeSum 

 from t_customer_monthlyincome where monthlyDate<to_char(sysdate,'yyyy-MM') group by customerCode)

  ajoin 

 (select customerCode,sum(focusMonthlyIncome) focusMonthlyIncomeSum fromt_customer_focusmonthlyincome 

 wherefocusMonthlyDate<to_char(add_months(trunc(sysdate),-12),'yyyy-MM') group bycustomerCode)b 

  ona.customerCode=b.customerCode;

 fetch p_cursor into jslRecord;

 loop

    insert into t_srbylAndZzjevalues(jslRecord.customerCode,jslRecord.zzje,jslRecord.byl);

  endloop;

end p_srbylAndZzje;

即是把计算出来的结果插入到另一张表里面.(此方法好像有问题,没成功 但思路是这样。)

可以用定时器让他执行

 可以在plsqldevelopersql窗口中来建立oracle job

declare  

job number;     

begin

sys.dbms_job.submit(job,'prc_g_test;',sysdate,'sysdate+1/1440');参数分别是job名存储过程名当前时间最后是每一分钟执行一次

end;(sql窗口中执行)

运行JOB(在command  即命令窗口)
  SQL> begin
   2 dbms_job.run(:job);
   3 end;
   4 /

 

从网上看的 项目里面需要使用存储过程场景 的总结:(自己还没完全理解)

计算业务性的数据报表数据.适宜用存储过程.

存储过程固然有它不可替代的好处。

但你也要权衡是让数据库服务器负担更多的运算量,还是交给应用服务器

 存储过程帮助大的即席查询减少网络流量。编写应用程序调用而不是500行的SQL调用来执行存储过程,对网络以及应用程序的性能有正面影响,特别是当调用在一分钟内重复数千

 次时。这个确实是存储过程的优点,对于较大且固定的查询(不拼接SQL)逻辑确实不错,可以节约数据传输量与SQL语句解析开销。

SQL语句本就不应该有复杂的逻辑控制,多数时候这更应该是程序逻辑。多数时候用数据库实现复杂的逻辑控制比程序实现代价大很多。

 当一个业务同时对多个表进行操作的时候可以用存储过程.

 所谓存储过程(Stored Procedure),就是一组用于完成特定数据库功能的SQL语句集,该SQL语句集经过编译后存储在数据库系统中。在使用时候,用户通过指定已经定义的存储过程名字并给出相应的存储过程参数来调用并执行它,从而完成一个或一系列的数据库操作。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值