oracle的储存过程学习

一、储存过程适用范围:将数据表中表A的数据组装写入导入表B中,运行速度很快。

二、储存过程包含体、头和方法

1.头的基本语法
-------头部申明
create or replace package PKG_DATA is PRAGMA SERIALLY_REUSABLE;
--------声明一种类型为T_CURSOR,可输出为一个对象
TYPE T_CURSOR IS REF CURSOR;
------输出的类型为T_CURSOR类型,输入类型为P_DATE
PROCEDURE GET_DATA(P_DATE IN DATE,P_PROCESS_CODE OUT VARCHAR2,p_cursor OUT T_CURSOR);
------头部结束
end PKG_DATA;

// todo
方法头的声明

2.体的基本语法
create or replace package body PKG_SEC_DATA is 
 PRAGMA SERIALLY_REUSABLE;
 PROCEDURE GET_DATA (p_cursor OUT T_CURSOR)  is 
 v_limit number;
 BEGIN
select nvl(to_number(C.config_value),1000) 
into vlimit
from SEC_INFO c
where c.config_type = 'sec_gen'
and c.config_id = 'sec_single_num' 
for update;

update sec_list
set flag =98’
where falg = '00'
and date_updated > sysdate -3
and rownum <= v_limit;

open p_cursor for 
select t.id reportId,
t.policy_no reportNo,
t.PRT_DATR bizDateStr
from SEC_LIST
WHERE t.flag = '98'
and date_updated >sysdate - 3;

update REPORT_LIST t
set t.falg= '99'
where t.falg= '98'
and DATE_UPDATED >sysdate - 3;

commit;
EXCEPTION
where OTHERS THEN 
ROLLBACK;------事务回滚
RAISE;-----将异常抛出去
	end GET_DATA ;
end PKG_SEC_DATA;
3.方法的基本语法

关键字function
①头的申明

function add (V_INPUT in varchar2) return NUMBER;

②体的语法

Function FUNC_TIMES (V_INPUT in varchar2) RETURN NUMBER is 
v_due_times NUMBER := 0;
cursor c_over_times(P_ACCT_NO VARCHAR2,P_DATE DATE) IS 
select count(distinct log.plan_id) over_due_times from cfs_plan_log log where log.acct_no = P_ACCT_NO AND log.change_type = '00' AND log.product_mode = 'PL_WS';
begin 
<<v_overdue_time_analysis>>
FOR v_overdue_times in c_over_times(P_ACCT_NO,P_DATE) loop
v_due_times := nvl(v_overdue_times.over_due_times,0);
end loop v_overdue_time_analysis;
return v_due_times;
end FUNC_TIMES;

4.游标的使用与变量的使用

① 储存过程从begin开始,游标用到时才触发

--方法开始,声明变量
v_potout_amt  NUMBER (12,2);


CURSOR v_putout_info(p_acct_no VARCHAR2,p_date DATE) IS

---客户名字、年龄、放款金额
SELECT  custName,age,putoutAmt from cust_info;
--执行从begin开始

begin
--游标v_putout_info 

<<v_putput_amt_analysis>>
FOR v_putout_info in c_putout_amt (p_acct_no,p_date) loop
v_potout_amt := nvl (c_putout_amt.putoutAmt,0);---变量

END loop v_putout_amt_analysis;

② 批量插入的写法

inset into SIGN_CHANGE
(created_by,
code,
FIR_BUSS_NUM)
(select 'ZHANGWEI',
'202'
t.policy_no) 
from 
(select t.policy_no from PHDRP_SEC_LB
where t.finish_date is null
)

5.存储过程定义数据类型
declare
type IdList is table of SEC_LIST_FD.ID_SEC_LIST_FD%type;
v_id Idlist;
cursor mycursor is select h.ID_SEC_LIST_FD from 
SEC_LIST_FD where h.flag = '00'

三、储存过程的调用

1.sql层

xml配置文件

<parameterMap id = "reportDataParamMap" class = "Map" >
	<parameter property = "result" javaType = "java.sql.ResultSet" jdbcType = "ORACLECURSOR" mode = "OUT"/>
	<parameter property = "P_DATE" javaType = "java.lang.String" jdbcType = "VARCHAR" mode = "IN"/>
	<parameter property = "P_PROCESS_CODE" javaType = "java.lang.String" jdbcType = "VARCHAR" mode = "OUT"/>
	<parameter property = "P_PROCESS_MSG" javaType = "java.lang.String" jdbcType = "VARCHAR" mode = "OUT"/>
<parameterMap/>

<proceduce id = "runSignDate" parameterMap = "reportDataParamMap">---parameterMap对应xnl文件配置
{
call cfodsode.PKG_SEC_SIGCHAN_LIST_CX.CX_OTHER_SIGCHAN_DATA(?,?,?,?)
}

</proceduce>
2.dao层
 public void runCXDAta(String reportDate){
        Map<String,Object> param = new HashMap<>();
        param.put("P_DATESTR",reportDate);
        param.put("P_PROCESS_CODE","");
        param.put("P_PROCESS_MSG","");
        param.put("result","");
        getSqlMaopClientTemplate().update("runSignDate",param);
        log.info("储存过程返回值P_PROCESS_CODE为"+param.get("P_PROCESS_CODE"));
        log.info("储存过程返回值P_PROCESS_MSG为"+param.get("P_PROCESS_MSG"));
    }

四、从储存过程中返回一个对象

1.PKG的写法

1.头部的声明

-------头部申明
create or replace package PKG_DATA is PRAGMA SERIALLY_REUSABLE;
--------声明一种类型为T_CURSOR,可输出为一个对象
TYPE T_CURSOR IS REF CURSOR;
------输出的类型为T_CURSOR类型,输入类型为P_DATE
PROCEDURE GET_DATA(P_DATE IN DATE,P_PROCESS_CODE OUT VARCHAR2,p_cursor OUT T_CURSOR);
------头部结束
end PKG_DATA;

2.体部的写法,p_cursor是名称,输出,类型为T_CURSOR.

create or replace package body PKG_SEC_DATA is 
 PRAGMA SERIALLY_REUSABLE;
 PROCEDURE GET_DATA (p_cursor OUT T_CURSOR)  is 
 v_limit number;
 BEGIN
select nvl(to_number(C.config_value),1000) 
into vlimit
from SEC_INFO c
where c.config_type = 'sec_gen'
and c.config_id = 'sec_single_num' 
for update;

update sec_list
set flag =98’
where falg = '00'
and date_updated > sysdate -3
and rownum <= v_limit;

open p_cursor for 
select t.id reportId,
t.policy_no reportNo,
t.PRT_DATR bizDateStr
from SEC_LIST
WHERE t.flag = '98'
and date_updated >sysdate - 3;

update REPORT_LIST t
set t.falg= '99'
where t.falg= '98'
and DATE_UPDATED >sysdate - 3;

commit;
EXCEPTION
where OTHERS THEN 
ROLLBACK;------事务回滚
RAISE;-----将异常抛出去
	end GET_DATA ;
end PKG_SEC_DATA;
2.java调用PKG的代码

xml配置

<parameterMap id = "secReportDataParamMap" class="map">
	<parameter property = "result" javaType = "java.sql.ResultSet" jdbcType = "ORACLECURSOR" mode = "OUT" resultMap = "secReportDataMap">
</parameterMap>
<resultMap id = "secReportDataMap" class= "com.icore.secondary.reportBuild.dto.SecProductBaseInfoDto">
	<result property = "reporNo" column = "reportNo">
	<result property = "scence" column = "scence">
</resultMap>
<proceduce id = "getDtoByOracle" parameterMap = "secReportDataParamMap">---parameterMap对应xnl文件配置
{
call cfodsode.PKG_DATA .GET_DATA(?)
}

dao层

 public void runCXDAta(String reportDate){
        Map<String,Object> param = new HashMap<>();     
        List result = getSqlMaopClientTemplate().update("getDtoByOracle",param);
        if (param.containKey("result")){
        	result = (List(SecProductBaseInfoDto))param.get("result");
        }
		param.get("result");
    }

五、oracle中实现遍历

create or replace package body PKG_SEC_DATA is 
 PRAGMA SERIALLY_REUSABLE;
 PROCEDURE GET_DATA (p_cursor OUT T_CURSOR)  is 
 v_limit number;  ---查询条数上限
 result_num number;
 execute_sql varchar(5000) :='';
 type num_list is varray(3) of varchar(3);
 body_arry num_list := num_list('','_FD','_TJ')
 --语法结构   变量名   变量类型  赋值符号
 BEGIN
select nvl(to_number(C.config_value),1000) 
into vlimit
from SEC_INFO c
where c.config_type = 'sec_gen'
and c.config_id = 'sec_single_num' 
for update;

for i in 1 .. body_arry.count loop
---拼接SQL语句
execute_sql := 'update sec_list' || body_arrry(i) ||' t set t.flag = 98 where t.flag = 00 and trunc(t.date_updated) > trunc(sysdate) - 3 and rownum <=' || v_limit;

execute immediate execute_sql;---执行SQL语句
result_num = sql% rowcount; ---判断SQL是否有更新到

if result_num <= 0 then continue;
end if;
if body_arry(i) is null then 
open p_cursor for select t.policy_no reportNo
from sec_list t where t.falg = '98';
else if '_FD' = body_arry(i) then 
open p_cursor for select t.policy_no reportNo
from sec_list_FD t where t.falg = '98';
else if '_TJ' = body_arry(i) then 
open p_cursor for select t.policy_no reportNo
from sec_list_TJ t where t.falg = '98';
end if;
execute_sql :='update sec_list' || body_arry(i) || 't set t.flag= 99 where t.flag = 98';
execute immediate execute_sql;
exit;---跳出本次循环

end loop;
commit;
 
EXCEPTION
where OTHERS THEN 
ROLLBACK;------事务回滚
RAISE;-----将异常抛出去
	end GET_DATA ;
end PKG_SEC_DATA;

六、oracle中实现SQL语句传参

for i in 1..24 loop 
  select add_months(P_E_DATE,i-24) into V_HIS_E_DATE from dual;
  v_sql = 'merge into zw_stat_mas l 
  using (select cp.acct_no,nvl(:1-min(cp.payment_date),0) odays from zw_plan
   where cp.product_mode = ''PL_WS'' and cp.plan_status in (''1'',''2'') and 
   ((cp.grace_for_date < trunc(cp.date_settle) 
   and trunc(cp.payment_date,''MM'') < trunc(cp.date_settle,''MM'') 
   and cp.date_settle > :3 ) or cp.date_settle is
    null) group by cp.acct_no) p
    on (l.acct_no = p.acct_no) 
    when matched then 
    update set l.overduedays_mon_'||i |
' = odays';
execute immediate v_sql using V_HIS_E_DATE ,V_HIS_E_DATE ,V_HIS_E_DATE ;
commit;

七、异常处理

begin 
select config_value into v_bank_code from 
zw_info phd where phd.config_type = 'xa_zed' 

exception 
when others then v_bank_code := 'N10155840H0001'
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值