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;