存储过程详解

2012-12-18 13:38:40

学了几天的存储过程,拿一个写好的例子来回顾一下,挺全面的

  1 PROCEDURE P_NAME(P_TASK_ID INTEGER, P_ACCT_DATE VARCHAR2) IS     
  2 --输入输出参数类型只能定义varchar2不能指定其范围  参数和变量是不同的 参数不受约束不能指定数据长度  只能指定数据类型
  3 --存储过程带括号必须要带参数 如果不带参数的话不要加括号  执行用exec 存储过程名(参数)
  4 --is后面加声明变量 is必须有 声明的变量后面得加上分号
  5 -- procedure test( indata in tablename.tableid%type,outdata  out number)
  6 /*
  7 *定义一个存储过程,其中输入参数indata的类型跟tablename表的tableid字段类型一样 
  8 *主要作用定义相同数据类型的变量
  9 *%TYPE是跟表中的字段的类型一致,是变量类型.而%ROWTYPE是跟表中的行类型一致,是record类型.
 10 *存储过程开始的标志 begin  结束end 存储过程名
 11 *while 条件 then
 12 *循环loop  end loop; 游标使用前必须打开,完了必须得关掉
 13 *if 条件 then 操作语句 end if;每个if操作必须对应一个end if
 14 *例如 if 条件 then 操作语句 else 操作语句end if;  在操作语句里面也可以嵌套if语句
 15 *case when 条件 then 操作语句 else 操作语句;
 16 */ 
 17 
 18         CURSOR  MAIN_CUR IS         --声明变量的饿时候必须赋初始值 且不能声明为varchar2类型必须指定范围
 19         SELECT*FROM ETR_LOAN;    --①定义一个游标
 20         IDX          MAIN_CUR%ROWTYPE; --①定义一个游标变量  该变量跟main_cur一样属于记录类型
 21         V_START_TIME TIMESTAMP := SYSDATE;        -- :=这个是赋值操作
 22         V_PROC_NAME  VARCHAR2(100) := 'p_etr_to_sta_loan';
 23         V_PROC_NOTE  VARCHAR2(100) := '测试';
 24         V_LOG_NOTE   VARCHAR2(2000) := '';
 25         COUNTER      INTEGER := 0;
 26         LOAN_NO_DATA EXCEPTION;            --定义一个异常名字
 27         PRAGMA EXCEPTION_INIT(LOAN_NO_DATA, -20101);        --PRAGMA在编译时处理    
 28         --EXCEPTION_INIT告诉编译器将异常名与ORACLE错误码结合起来 error_number是一个范围在-20000至-20999之间的负整数(自己定义的异常)
 29     BEGIN
 30     
 31         open cursor;        --②打开游标
 32         LOOP                --开启循环
 33             FETCH MAIN_CUR    --操作数据  把当前游标提取的值赋给变量idx
 34                 INTO IDX;
 35             EXIT WHEN MAIN_CUR%NOTFOUND;
 36             IF IDX.N_CTRT_AMT <> IDX.O_CTRT_AMT THEN              --if 判断条件 then 操作语句 
 37                 具体的操作语句
 38             END IF;
 39         END LOOP;
 40         CLOSE MAIN_CUR;    --游标使用完必须关闭
 41         
 42         --写入日志
 43         SELECT COUNT(*)
 44             INTO COUNTER
 45             FROM ETR.ETR_LOAN
 46          WHERE DATA_DATE = TO_DATE(P_ACCT_DATE, 'yyyymmdd');
 47         IF COUNTER > 0 THEN
 48             INSERT /*+append*/
 49             INTO ETR_TO_STA_LOAN
 50                 (
 51                 --字段
 52                  )
 53                 SELECT 
 54                              CASE
 55                                  WHEN TRIM(LOAN.CCY) IS NULL THEN
 56                                     '999'
 57                                  ELSE
 58                                     NVL((SELECT WS.CODE
 59                                                 FROM WEB_SYS_PARAMETER WS
 60                                              WHERE WS.CODE = TRIM(LOAN.CCY)
 61                                                  AND WS.TYPE = 'A020'),
 62                                             '998')
 63                              END CCY, 
 64                              
 65                              CASE
 66                                  WHEN TRIM(LOAN.IDENTLEVEL) IN
 67                                             ('1', '2', '3', '4', '5', '6') THEN
 68                                     '1'
 69                                  WHEN TRIM(LOAN.IDENTLEVEL) IN ('7', '8', '9', '10') THEN
 70                                     '2'
 71                                  WHEN TRIM(LOAN.IDENTLEVEL) IN ('11', '12') THEN
 72                                     '3'
 73                                  WHEN TRIM(LOAN.IDENTLEVEL) = '13' THEN
 74                                     '4'
 75                                  WHEN TRIM(LOAN.IDENTLEVEL) = '14' THEN
 76                                     '5'
 77                                  ELSE
 78                                     '9'
 79                              END LOAN_QUTY_TYPE_CD,
 80                     FROM ETR.ETR_LOAN LOAN
 81                  WHERE LOAN.DATA_DATE = TO_DATE(P_ACCT_DATE, 'yyyymmdd');
 82             V_LOG_NOTE := P_ACCT_DATE || V_PROC_NOTE || '处理数据量【' ||--||是拼接符号
 83                                         SQL%ROWCOUNT || '';        --SQL%ROWCOUNT 影响的记录条数,必须放在commit之前
 84             COMMIT;
 85             --插入日志信息
 86         
 87         ELSE
 88             RAISE_APPLICATION_ERROR(-20101,
 89             --RAISE_APPLICATION_ERROR 是将应用程序专有的错误从服务器端转达到客户端应用程序   可以用sqlerrm获取  这个地方的异常号对应开始定义的
 90             --raise_application_error(异常类型,传递信息)异常类型:number() 值域:-20000 到-20999传递信息:varchar2(2000)
 91                                                             'ETR_LOAN表中无' || P_ACCT_DATE || '日的数据');
 92         END IF;
 93         --异常的处理,相当于对事务的操作
 94     EXCEPTION
 95         WHEN LOAN_NO_DATA THEN        --当声明的错误发生时
 96             V_LOG_NOTE := COM_UTILITY.F_GET_ERRINFO();        --执行com_utility包下面的f_get_errorinfo()函数,得到结果字段穿
 97         WHEN OTHERS THEN            --当其他错误时 回滚
 98         --当没有已经定义好了的EXCEPTION NAME可用时,我们就用OTHERS来处理未被捕捉的所有的EXCEPTION
 99             ROLLBACK;
100             V_LOG_NOTE := COM_UTILITY.F_GET_ERRINFO();
101     END P_NAME;--结尾的地方必须加分号

 存储过程

for in loop用法1:

DECLARE
v_date date;
BEGIN
EXECUTE IMMEDIATE 'truncate table etl_date';
for v_date in 20091001 .. 20091021 LOOP
    INSERT INTO etl_date
      (date_char, date_date)
      SELECT v_date, to_date(v_date, 'YYYY-MM-DD') FROM dual;
END LOOP;
COMMIT;
END;

用法2:

declare
P_TABLE_NAME varchar2(100) := 'CFA';
begin
for HZ in (select HZ_NAME from HZ) LOOP
    insert into sqltext
      select 'CREATE TABLE ' || REPLACE(P_TABLE_NAME, 'EDW', 'TMP') ||
             HZ.HZ_NAME || ' AS select * from ' || P_TABLE_NAME ||
             ' where ROWNUM<1'
        from dual;
END LOOP;
end;
原文地址:https://www.cnblogs.com/javahuang/p/2823137.html