Bootstrap

oracle ~ 存储过程模板

前言:

写存储过程很简单,但是要是想写报错日志等详细的信息的存储过程,就比较麻烦,现在从头开始找个列子以防忘记。
当然,如果不想写这么麻烦,直接写一个最简单的就行,参考最后一步

一:建立存储过程执行状态表及log表

执行状态表

create table ERMP_LOG.ERMP_DATASTATUS
(
  business_date          NUMBER(10) default 0 not null,
  program_id             NUMBER,
  report_no              VARCHAR2(128) default ' ' not null,
  data_status            CHAR(1) default ' ',
  report_rownum          NUMBER(38) default 0,
  version_no             NUMBER(10) default 0,
  created_by             VARCHAR2(128) default ' ',
  last_modify_by         VARCHAR2(128) default ' ',
  creation_date          TIMESTAMP(6) default SYSDATE,
  last_modification_date TIMESTAMP(6) default SYSDATE,
  remark                 VARCHAR2(2000) default ' ',
  start_time             TIMESTAMP(6),
  end_time               TIMESTAMP(6),
  noready_program        VARCHAR2(2000)
)

log表

create table ERMP_LOG.ERMP_DATAOPERLOG
(
  business_date          NUMBER(10) default 0 not null,
  seq_id                 NUMBER,
  program_id             NUMBER,
  report_no              VARCHAR2(128) default ' ' not null,
  deal_status            CHAR(1) default ' ',
  report_rownum          NUMBER,
  version_no             NUMBER(10) default 0,
  created_by             VARCHAR2(128) default ' ',
  last_modify_by         VARCHAR2(128) default ' ',
  creation_date          TIMESTAMP(6) default SYSDATE,
  last_modification_date TIMESTAMP(6) default SYSDATE,
  remark                 VARCHAR2(2000) default ' ',
  error_daily_analysis   NVARCHAR2(1000)
)

二:创建序列 Sequence

create sequence ERMP_SCHEDULE.SEQ_PROC_ID
minvalue 1
maxvalue 9999999999999999999999999999
start with 1080381
increment by 1
cache 20;

三:创建日志存储过程

create or replace procedure ermp_schedule.p_ermp_dataoper(p_business_date number default 0,--处理日期
                                             --  p_company_no    number default 0,
                                               p_seq_id        number default 0,
                                               P_program_id    number default 0,
                                               p_report_no     varchar2 default ' ',--存储过程名
                                               p_deal_status   number default 0,--处理状态
                                               p_created_by    varchar2 default ' ',--创建人、修改人
                                               p_version_no    number default 0,--版本
                                               p_remark        varchar2 default ' ',--备注
                                               p_data_num      number default 0--数据处理量
                                               ) as
  /***************************************************************
   功能描述:插入存储过程执行状态表及log表
   输入参数:数据处理日期,对应table名称,处理状态,创建人,版本号,备注,数据处理数量
   输出参数:无
   源头表:
  无
  目的表:
  ERMP_LOG.ERMP_DATASTATUS
  ERMP_LOG.ERMP_DATAOPERLOG
  调用存储过程:无
  被调用存储过程:无
  创建人:DUBikang
  创建日期:20181219
  版本说明:1.0
  备注:状态表:0开始执行,1执行成功,2之后执行失败
        log表:0开始存储过程,1执行存储过程成功,2执行存储过程失败
    ***************************************************************/
  v_sql varchar2(4000);
  v_program_id number;
  v_count number;
  v_period_3 number;
  --v_update_sql varchar2(4000);
 -- v_count      number;
begin
  v_program_id:=P_program_id;
  if nvl(v_program_id, 0) = 0 then
    select count(distinct program_id) into v_count
      from ermp_schedule.ermp_proc_cfg a
     where lower(a.proc_name) = lower(p_report_no);
    if v_count = 1 then
      select distinct a.program_id into v_program_id
        from ermp_schedule.ermp_proc_cfg a
       where lower(a.proc_name) = lower(p_report_no);
    else
      dbms_output.put_line('report_no有误');
      return;
    end if;
  end if;
  
  select t.period_id into v_period_3 from
    (select a.period_id, row_number()over(order by a.period_id desc)rn
       from ermp_sour.period_dim a
      where a.period_level = 'D'
        and a.working_day_flag = 'Y'
        and a.period_id < to_char(sysdate,'yyyymmdd')
     order by a.period_id)t
     where t.rn = 3;

--插入日志--
  merge into ermp_log.ermp_dataoperlog t1
   using (select p_business_date a, p_seq_id b, v_program_id  c, p_report_no d, p_deal_status e,
                 p_created_by f, p_version_no g, p_remark h, p_data_num i from dual) t2
      on ( t1.business_date=t2.a and t1.program_id=t2.c and t1.seq_id = t2.b)
    when matched then
         update set deal_status = p_deal_status, remark = p_remark,report_rownum = p_data_num,
         last_modification_date = systimestamp,last_modify_by = p_created_by
    when not matched then
         insert (business_date, seq_id, program_id, deal_status, report_no, remark, report_rownum, creation_date, created_by)
         values (p_business_date, p_seq_id, v_program_id, p_deal_status, p_report_no, p_remark, p_data_num, systimestamp, p_created_by);


  if (p_deal_status = 0) then

   MERGE INTO ermp_log.ermp_datastatus T1
   USING (SELECT p_business_date a, v_program_id  b FROM dual) T2
      ON ( T1.business_date=T2.a and T1.program_id=T2.b)
    WHEN MATCHED THEN
         UPDATE SET data_status = 0, remark = ' ',report_rownum = p_data_num,start_time = systimestamp,
                    end_time = '',last_modification_date = systimestamp,LAST_MODIFY_BY = p_created_by
    WHEN NOT MATCHED THEN
         insert (business_date, program_id, data_status,  report_no, start_time, remark,report_rownum,CREATED_BY)
         values (p_business_date, v_program_id, 0, p_report_no, systimestamp, ' ',p_data_num,p_created_by);

  elsif (p_deal_status = 1) then

   MERGE INTO ermp_log.ermp_datastatus T1
   USING (SELECT p_business_date a, v_program_id  b FROM dual) T2
      ON ( T1.business_date=T2.a and T1.program_id=T2.b)
    WHEN MATCHED THEN
         UPDATE SET   data_status = 1, remark = ' ',report_rownum= p_data_num,end_time=systimestamp,
                      last_modification_date = systimestamp,LAST_MODIFY_BY=p_created_by
    WHEN NOT MATCHED THEN
         insert (business_date, program_id, report_no, data_status,end_time, remark,report_rownum,CREATED_BY)
         values (p_business_date, v_program_id, p_report_no, 1,systimestamp, ' ',p_data_num,p_created_by);
   commit;
   --执行相关依赖过程的调度
   select count(1) into v_count
     from ermp_schedule.ermp_proc_cfg a,
          table(ermp_schedule.func_split(a.rela_program, ',')) b
    where trim(b.column_value) = v_program_id
      and a.is_valid = 1
      and a.run_type = 1;
   if v_count > 0 and p_business_date >= v_period_3 then 
     ermp_schedule.p_call_rela_proc(p_business_date => p_business_date,
                                    p_program_id => v_program_id);
   end if;
  elsif (p_deal_status = 2) then

    MERGE INTO ermp_log.ermp_datastatus T1
    USING (SELECT p_business_date a, v_program_id  b FROM dual) T2
       ON ( T1.business_date=T2.a and T1.program_id=T2.b)
     WHEN MATCHED THEN
          UPDATE SET  data_status = 2, remark = p_remark,report_rownum= 0,
                      last_modification_date = systimestamp,LAST_MODIFY_BY=p_created_by
     WHEN NOT MATCHED THEN
          insert (business_date, program_id, report_no, data_status, remark,report_rownum,CREATED_BY)
          values (p_business_date, v_program_id, p_report_no, 2, p_remark,0,p_created_by);
    else
      MERGE INTO ermp_log.ermp_datastatus T1
    USING (SELECT p_business_date a, v_program_id  b FROM dual) T2
       ON ( T1.business_date=T2.a and T1.program_id=T2.b)
     WHEN MATCHED THEN
          UPDATE SET  data_status = p_deal_status, remark = p_remark,report_rownum= 0,
                      last_modification_date = systimestamp,LAST_MODIFY_BY=p_created_by
     WHEN NOT MATCHED THEN
          insert (business_date, program_id, report_no, data_status, remark,report_rownum,CREATED_BY)
          values (p_business_date, v_program_id, p_report_no, p_deal_status, p_remark,0,p_created_by);

    end if;
     commit;


end p_ermp_dataoper;


四:创建平常使用的存储过程

CREATE OR REPLACE PROCEDURE ERMP_DATA.JGBM_JRCXB_BYLBD_PROC(
                                                      p_business_date number, --执行日期
                                                      p_created_by  varchar2 --执行人
                                                     ) is
  /***************************************************************
   功能描述:报表库-公募基金风险关注池-保有量变动
   输入参数:p_business_date  执行日期
            p_created_by varchar2  执行人

   输出参数:
   源头表:ERMP_SOUR.T_CPFX_GMJJGZC
   目的表:ermp_data. ERMP_DATA.JGBM_JRCXB_BYLBD
  调用存储过程:无
  被调用存储过程:无
  创建人:du
  创建日期:20190731
  备注:
  版本说明:1.0
***************************************************************/
  --系统变量---
  v_table_no        varchar2(200); --插入表
  v_version_no      varchar2(200); --版本
  v_created_by      varchar2(200); --执行人
  v_report_data_num number; --处理数据数量
  v_business_date   number;
  v_business_date_1   number;--前一个工作日
  v_seq_id          number;
  --框架变量--

begin
    --系统变量赋值
  v_business_date := p_business_date;
  v_version_no := v_business_date || '01';
	select max(period_id) into v_business_date_1 from ermp_data.period_dim
            where period_level ='D' and WORKING_DAY_FLAG='Y'
            and period_id < v_business_date;

  v_table_no   := 'ERMP_DATA.JGBM_JRCXB_BYLBD_PROC';
  if length(p_created_by) > 3 then
    v_created_by := p_created_by;
  else
    select sys_context('USERENV', 'SESSION_USER')
      into v_created_by
      from dual;
  end if;
  --记录日志
  v_seq_id := ermp_schedule.seq_proc_id.nextval;
  ermp_schedule.p_ermp_dataoper(p_business_date => v_business_date,
                       p_seq_id        => v_seq_id,
                       p_report_no     => v_table_no,
                       p_deal_status   => 0,
                       p_created_by    => v_created_by,
                       p_version_no    => v_version_no,
                       p_remark        => '');


  ----抽取数据----

  delete ERMP_DATA.JGBM_JRCXB_BYLBD a
   where a.partition_id = to_date(v_business_date, 'yyyymmdd');

  insert into ERMP_DATA.JGBM_JRCXB_BYLBD
  (partition_id, period_id, srv_branch_no, srv_branch_name, srv_up_no, srv_up_name, prdt_code, prdt_abbr, category_name, risk_level,
   stock_nav, buy_amt_y, hold_amt_y, cust_num, attention_type, recommended_opinion, evaluation_time, up_src_lev, up_lev,
   up_dt, hold_amt_prop, hold_amt_change, data_src, nav_date)
  with  TEMP2 AS(select a.period_id --日期
      ,a.org_id --营业部id
      ,a.up_org_id --分公司编码
      ,a.prdt_code --产品代码
      ,a.hold_amt_y hold_amt_y_1 --保有量
      ,a.data_src --数据来源
  from ERMP_SOUR.T_CPFX_GMJJGZC a
 where a.period_id = v_business_date_1),
 tmp1 as
(select distinct a.period_id --日期
      ,a.org_id --营业部id
      ,a.org_name --营业部名称
      ,a.up_org_id --分公司编码
      ,a.up_org_name --分公司名称
      ,a.prdt_code --产品代码
      ,a.prdt_abbr --产品简称
      ,a.category_name --产品类型
      ,decode(a.risk_level, '1', '高风险', '2', '中高风险', '3', '中风险', '4', '中低风险', '5', '低风险', a.risk_level) risk_level --产品风险等级
      ,a.stock_nav --产品净值
      ,a.buy_amt_y --总销量
      ,a.hold_amt_y --保有量
      ,a.cust_num --客户数量
      --, a.attention_type --关注类型
      ,substr(case when a.recommended_opinion is not null then ',跟踪评价意见变动' end ||
       case when a.up_dt is not null then ',风险等级变更' end ||
       case when a.hold_amt_change is not null then ',保有量变动' end, 2) attention_type
      ,a.recommended_opinion --跟踪评价意见
      ,a.evaluation_time --评价日期
      ,decode(a.up_src_lev, '1', '高风险', '2', '中高风险', '3', '中风险', '4', '中低风险', '5', '低风险', a.up_src_lev) up_src_lev --原风险等级
      ,decode(a.up_lev, '1', '高风险', '2', '中高风险', '3', '中风险', '4', '中低风险', '5', '低风险', a.up_lev) up_lev --变更后等级
      ,a.up_dt --变更日期
      ,a.hold_amt_prop --保有量占比
      ,decode(b.hold_amt_y_1,0,null,a.hold_amt_y/b.hold_amt_y_1 -1) hold_amt_change --保有量变动率
			,ROW_NUMBER() OVER(PARTITION BY a.org_id,a.up_org_id,a.data_src ORDER BY decode(b.hold_amt_y_1,0,null,a.hold_amt_y/b.hold_amt_y_1 -1) )  BYLBD_PX
      ,a.data_src --数据来源
      ,a.nav_date
  from ERMP_SOUR.T_CPFX_GMJJGZC a left join TEMP2 b on a.org_id = b.org_id and a.up_org_id = b.up_org_id and a.prdt_code = b.prdt_code
	and a.data_src = b.data_src
 where a.period_id = v_business_date
 AND a.hold_amt_change is not null )
 select to_date(a.period_id, 'yyyymmdd') as partition_id
        ,a.period_id
        ,a.org_id --分公司编码
        ,a.org_name --分公司名称
        ,a.up_org_id --营业部编号
        ,a.up_org_name --营业部名称
        ,a.prdt_code --产品代码
        ,a.prdt_abbr --产品简称
        ,a.category_name --产品类型
        ,max(a.risk_level) risk_level --产品风险等级
        ,max(a.stock_nav) stock_nav --产品净值
        ,sum(a.buy_amt_y) buy_amt_y --总销量
        ,sum(a.hold_amt_y) hold_amt_y --保有量
        ,sum(a.cust_num) cust_num --客户数量
        ,a.attention_type --关注类型
        ,max(a.recommended_opinion) recommended_opinion --跟踪评价意见
        ,max(a.evaluation_time) evaluation_time --评价日期
        ,max(a.up_src_lev) up_src_lev --原风险等级
        ,max(a.up_lev) up_lev --变更后等级
        ,max(a.up_dt) up_dt --变更日期
        ,sum(a.hold_amt_prop) hold_amt_prop --保有量占比
        ,sum(a.hold_amt_change) hold_amt_change --保有量变动率
        ,Decode(GROUPING(a.data_src), 1, '999', a.data_src) data_src
        ,max(a.nav_date) nav_date--净值日期
   from tmp1 a
	 WHERE A.BYLBD_PX <= 10
  GROUP BY GROUPING SETS((a.Period_Id, a.org_id, a.org_name, a.up_org_id, a.up_org_name, a.data_src, a.prdt_code, a.prdt_abbr, a.CATEGORY_NAME, a.attention_type),
                         (a.Period_Id, a.org_id, a.org_name, a.up_org_id, a.up_org_name, a.prdt_code, a.prdt_abbr, a.CATEGORY_NAME, a.attention_type));



   --每次全量更新净值日期和评价日期数据

merge into ERMP_DATA.JGBM_JRCXB_BYLBD t
using
  (select a.secucode, c.tradingcode, b.enddate, a.netunit from center_admin.fnd_dernav a
      inner join
      (select secucode, max(enddate) as enddate from center_admin.fnd_dernav t group by t.secucode)b
      on a.secucode = b.secucode and a.enddate = b.enddate
      left join center_admin.fnd_basicinfo c
      on a.secucode = c.secucode
   where c.tradingcode is not null ) t1
on (t.prdt_code = t1.tradingcode)
when matched then
  update set t.new_stock_nav = t1.netunit
             ,t.new_stock_nav_date = to_number(to_char(t1.enddate, 'yyyyMMdd'))
;



  commit;

  select count(1) into v_report_data_num
    from ERMP_DATA.JGBM_JRCXB_BYLBD a
   where a.partition_id = to_date(v_business_date, 'yyyymmdd');
  --记录日志--
  ermp_schedule.p_ermp_dataoper(p_business_date => v_business_date,
                       p_seq_id        => v_seq_id,
                       p_report_no     => v_table_no,
                       p_deal_status   => 1,
                       p_created_by    => v_created_by,
                       p_version_no    => v_version_no,
                       p_remark        => '',
                       p_data_num      => v_report_data_num);
exception
  when others then
    --当失败,记录日志--
    ermp_schedule.p_ermp_dataoper(p_business_date => v_business_date,
                         p_seq_id        => v_seq_id,
                         p_report_no     => v_table_no,
                         p_deal_status   => 2,
                         p_created_by    => v_created_by,
                         p_version_no    => v_version_no,
                         p_remark        => dbms_utility.format_error_stack,
                         p_data_num      => v_report_data_num);
    rollback;

end  JGBM_JRCXB_BYLBD_PROC;

贼拉简单的版本

create or replace procedure ProcLogin_jiang(
     p_id in number,p_pwd in char,flag out number)--in表示输入,入口,默认值,out表示输出,出口
        is --定义变量
           v_password char(4);--数据表里面真正的密码
        begin                                --begin和end之间为程序体
           select password into v_password     --过程中的select语句的格式
             from user_xxx
             where id=p_id;                      --当且仅当查询出来一条记录时,不会出异常
               if p_pwd=v_password then
                   flag:=1;
               else 
                   flag:=0;
               end if;
     exception                              --当出现异常时,程序会跳到这里执行
         when others then
                   flag:=-1;       
        end;
;