本来标题是想想用使用oracle的心得体会的,不过想想自己也没什么体会,只是单纯的按照经理的要求用存储过程所以只是记录下哈哈。
项目是个比较小的项目。是地市的移动公司 管理,统计他们客户使用移动的产品像(宽带、固话、专线)情况以及这方面收入的情况。
需求是:开始他会把他们的客户集团去年十二个月的集团编码、月收入信息导入到系统中显示。然后当前年每月导入上月的所有集团的收入情况。一下举例说明:
这里只导入了 1到4月份的(应该是1到8月份的)
需求是要计算收入的保有率和增长金额。(集团数有一万条左右、)
保有率比如今年5月份的保有率就是当前2013年 1到四月份的收入和/去年2012年1月到4月的收入和.
5月份的增长金额就是就是当前2013年 1到四月份的收入和减去去年2012年1月到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;
即是把计算出来的结果插入到另一张表里面.(此方法好像有问题,没成功 但思路是这样。)
可以用定时器让他执行
可以在plsqldeveloper的sql窗口中来建立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语句集经过编译后存储在数据库系统中。在使用时候,用户通过指定已经定义的存储过程名字并给出相应的存储过程参数来调用并执行它,从而完成一个或一系列的数据库操作。