oracle创建-存储过程和函数

--创建存储过程

CREATE OR REPLACE PROCEDURE xxxxxxxxxxx_p(
                                          --参数IN表示输入参数,
                                          --OUT表示输出参数,类型可以使用任意Oracle中的合法类型。
                                          is_ym IN CHAR) AS
  --定义变量
  vs_msg       VARCHAR2(4000); --错误信息变量
  vs_ym_beg    CHAR(6); --起始月份
  vs_ym_end    CHAR(6); --终止月份
  vs_ym_sn_beg CHAR(6); --同期起始月份
  vs_ym_sn_end CHAR(6); --同期终止月份

  --定义游标(简单的说就是一个可以遍历的结果集)
  CURSOR cur_1 IS
    SELECT area_code,
           CMCODE,
           SUM(rmb_amt) / 10000 rmb_amt_sn,
           SUM(usd_amt) / 10000 usd_amt_sn
      FROM BGD_AREA_CM_M_BASE_T
     WHERE ym >= vs_ym_sn_beg
       AND ym <= vs_ym_sn_end
     GROUP BY area_code, CMCODE;

BEGIN
  --用输入参数给变量赋初值,用到了Oralce的SUBSTR TO_CHAR ADD_MONTHS TO_DATE 等很常用的函数。
  vs_ym_beg    := SUBSTR(is_ym, 1, 6);
  vs_ym_end    := SUBSTR(is_ym, 7, 6);
  vs_ym_sn_beg := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_beg, 'yyyymm'), -12),
                          'yyyymm');
  vs_ym_sn_end := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_end, 'yyyymm'), -12),
                          'yyyymm');
  --先删除表中特定条件的数据。
  DELETE FROM xxxxxxxxxxx_T WHERE ym = is_ym;
  --然后用内置的DBMS_OUTPUT对象的put_line方法打印出影响的记录行数,其中用到一个系统变量SQL%rowcount
  DBMS_OUTPUT.put_line('del上月记录=' || SQL%rowcount || '条');

  INSERT INTO xxxxxxxxxxx_T
    (area_code, ym, CMCODE, rmb_amt, usd_amt)
    SELECT area_code,
           is_ym,
           CMCODE,
           SUM(rmb_amt) / 10000,
           SUM(usd_amt) / 10000
      FROM BGD_AREA_CM_M_BASE_T
     WHERE ym >= vs_ym_beg
       AND ym <= vs_ym_end
     GROUP BY area_code, CMCODE;
  DBMS_OUTPUT.put_line('ins当月记录=' || SQL%rowcount || '条');

  --遍历游标处理后更新到表。遍历游标有几种方法,用for语句是其中比较直观的一种。
  FOR rec IN cur_1 LOOP
    UPDATE xxxxxxxxxxx_T
       SET rmb_amt_sn = rec.rmb_amt_sn, usd_amt_sn = rec.usd_amt_sn
     WHERE area_code = rec.area_code
       AND CMCODE = rec.CMCODE
       AND ym = is_ym;
  END LOOP;

  COMMIT;
  --错误处理部分。OTHERS表示除了声明外的任意错误。SQLERRM是系统内置变量保存了当前错误的详细信息。
EXCEPTION
  WHEN OTHERS THEN
    vs_msg := 'ERROR IN xxxxxxxxxxx_p(' || is_ym || '):' ||
              SUBSTR(SQLERRM, 1, 500);
    ROLLBACK;
    --把当前错误记录进日志表。
    INSERT INTO LOG_INFO
      (proc_name, error_info, op_date)
    VALUES
      ('xxxxxxxxxxx_p', vs_msg, SYSDATE);
    COMMIT;
    RETURN;
END;


--创建函数
create or replace function get_publicholidaytime(fromtime    in Date,
                                                 totime      in Date,
                                                 isAvailable in number)
  return number as
  --定义变量  
  free_day number := 0;
  mindate  Date;
  maxdate  Date;
  total    number := 0;
  fromdate Date := TO_DATE(to_char(fromtime, 'yyyy/MM/dd'), 'yyyy/MM/dd');
  todate   Date := TO_DATE(to_char(totime, 'yyyy/MM/dd'), 'yyyy/MM/dd');
begin
  --if语句  
  if isAvailable = 1 then
    --sql语句  
    select min(calendar_date), max(calendar_date), count(calendar_date)
      into mindate, maxdate, total
      from T_BI_TNT_DATE
     where calendar_date between fromdate and todate
       and IS_PUBLIC_HOLIDAY = 1;
    if mindate = fromdate then
      total    := total - 1;
      free_day := free_day + ((mindate + 1) - fromtime);
    end if;
    if maxdate = todate then
      total    := total - 1;
      free_day := free_day + (totime - maxdate);
    end if;
    if mindate = maxdate then
      free_day := totime - fromtime;
    else
      free_day := free_day + total;
    end if;
  end if;
  return free_day;
end get_publicholidaytime;


相关文档
Oracle存储过程创建及调用:http://www.cnblogs.com/chinafine/articles/1776094.html


两者区别:
技术分享
用来计算并返回一个计算结果而存储过程一般是用来完成特定的数据操作(比如修改、插入数据库表或执行某些DDL语句等等),所以虽然他们的语法上很相似但用户在使用他们的时候所需要完成的功能大部分情况下是不同的。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。