本文转自 https://www.cnblogs.com/lukelook/p/9600407.html,感谢博主 豆豆DE思念 整理分享。

1.Oracle 存储过程基本格式 

最简单的版本 is as 都可以

create or replace  procedure create_test
as
begin
dbms_output.put_line('1234');
end create_test;

调用

-- 1.如果是命令窗口就用exec 存储过程名,举个栗子:
EXEC procedure;--procedure是存储过程名 -- 2.如果是PL/SQL窗口就用 begin 存储过程名 end; 举个栗子:
begin
procedure;--procedure是存储过程名
end; -- 或者
execute proname;
-- 3.如果是程序中调用就用 call 存储过程名 ,举个栗子:
hibernateDao.excuteSqlUpdate("{Call proc_stuInfo()}");//存储过程proc_stuInfo

基本模版

create or replace PROCEDURE CREATE_TEST(
INPUT IN VARCHAR2,
OUTPUT OUT VARCHAR2
)
AS
MSG VARCHAR2(20) :='小红';
BEGIN
DBMS_OUTPUT.PUT_LINE(MSG); INSERT INTO TEST VALUES (INPUT,MSG);
END CREATE_TEST;

调用

declare
output VARCHAR2(20);
BEGIN
CREATE_TEST('15',output);
end;

注意在调用不是当前用户创建的一定要加上用户.

declare
output VARCHAR2(20);
BEGIN
look.CREATE_TEST('15',output);
end;

标准版本 添加异常处理模块和输入输出控制:

CREATE OR REPLACE PROCEDURE CREATE_TEST(
INPUT IN VARCHAR2,
OUT_CODE OUT INTEGER,
OUT_MSG OUT VARCHAR2
)
AS
MSG VARCHAR2(20) :='小红';
BEGIN DBMS_OUTPUT.PUT_LINE(MSG);
INSERT INTO TEST VALUES (INPUT,MSG);
OUT_CODE := SQLCODE;
OUT_MSG := 'OK';
EXCEPTION
WHEN OTHERS THEN
OUT_CODE := SQLCODE;--以前根据这个标识来判断过程是否执行成功
OUT_MSG := 'test:' || SQLERRM;
DBMS_OUTPUT.PUT_LINE(OUT_CODE || ':' || OUT_MSG);
RAISE;--用于抛出异常
END CREATE_TEST;

SQLCODE SQLERRM 是不能直接在sql语句中使用,必须先将其赋给变量后;

 自定义异常

CREATE OR REPLACE PROCEDURE CREATE_TEST(
INPUT IN VARCHAR2,
OUT_CODE OUT INTEGER,
OUT_MSG OUT VARCHAR2
)
AS
EXC EXCEPTION; BEGIN
IF(INPUT ='7') THEN
RAISE EXC;
--raise_application_error(-20000,'输入值不能为7!');
END IF; OUT_CODE := SQLCODE;
OUT_MSG := 'OK';
EXCEPTION
WHEN EXC THEN
DBMS_OUTPUT.PUT_LINE('====进入自定义异常模块====');
OUT_CODE := SQLCODE;--以前根据这个标识来判断过程是否执行成功
OUT_MSG := 'test:' || SQLERRM;
DBMS_OUTPUT.PUT_LINE(OUT_CODE || ':' || OUT_MSG);
RAISE;--用于抛出异常
WHEN OTHERS THEN
OUT_CODE := SQLCODE;--以前根据这个标识来判断过程是否执行成功
OUT_MSG := 'test:' || SQLERRM;
DBMS_OUTPUT.PUT_LINE(OUT_CODE || ':' || OUT_MSG);
RAISE;--用于抛出异常
END CREATE_TEST;

或者

create or replace PROCEDURE CREATE_TEST(
INPUT IN VARCHAR2,
OUT_CODE OUT INTEGER,
OUT_MSG OUT VARCHAR2
)
AS
EXC EXCEPTION; BEGIN
IF(INPUT ='7') THEN
--RAISE EXC;
raise_application_error(-20000,'输入值不能为7!');
END IF; OUT_CODE := SQLCODE;
OUT_MSG := 'OK';
EXCEPTION WHEN OTHERS THEN
OUT_CODE := SQLCODE;--以前根据这个标识来判断过程是否执行成功
OUT_MSG := 'test:' || SQLERRM;
DBMS_OUTPUT.PUT_LINE(OUT_CODE || ':' || OUT_MSG);
RAISE;--用于抛出异常
END CREATE_TEST;

模版1

--创建存储过程   
CREATE OR REPLACE PROCEDURE xxxxxxxxxxx_p   (   
--参数IN表示输入参数,   
--OUT表示输入参数,类型可以使用任意Oracle中的合法类型。   
is_ym IN VARCHAR2
v_out OUT VARCHAR2)   
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;

模版2

--模板二:   --ORACLE存储过程实例:   
CREATE OR REPLACE PROCEDURE CL_24_MONTHS_STATUS   
--(无输入/输出参数)   
IS   
--存储过程开始   
BEGIN   
DECLARE   
--声明变量   
V_OP_NUM CHAR(20);   
V_START_DATE DATE;   
V_END_DATE DATE;   
V_COUNT NUMBER;   
V_COUNT1 NUMBER;   
V_24MONTHS_FLAG VARCHAR(24);
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;

模版3

--模板二:   --ORACLE存储过程实例:   
CREATE OR REPLACE PROCEDURE CL_24_MONTHS_STATUS   
--(无输入/输出参数)   
IS   
--存储过程开始   
BEGIN   
DECLARE   
--声明变量   
V_OP_NUM CHAR(20);   
V_START_DATE DATE;   
V_END_DATE DATE;   
V_COUNT NUMBER;   
V_COUNT1 NUMBER;   
V_24MONTHS_FLAG VARCHAR(24);
V_DATE_OPENED DATE;   
V_MATURE_DATE DATE;   
V_OVERDUE NUMBER;   
V_STATUS CHAR(1);   
V_REPORTDATE DATE;   
V_BILLING_DATE1 DATE;   
V_BILLING_DATE2 DATE;   
--声明游标   
CURSOR OVERDUE_CURSOR IS   
SELECT OP_NUM,DATE_OPENED,MATURE_DATE,STATUS   
FROM CL_VALID_CONTRACT   
WHERE TERM_FREQ<>'5' ORDER BY OP_NUM;   
--程序体开始   
BEGIN   
OPEN OVERDUE_CURSOR;   
SELECT REPORTDATE INTO V_REPORTDATE FROM T_ETLDATE;   
DELETE FROM CL_MONTHS24_STATUS_TOTAL;   
LOOP   
V_24MONTHS_FLAG:='';   
V_END_DATE:=V_REPORTDATE;   
FETCH OVERDUE_CURSOR INTO V_OP_NUM,V_DATE_OPENED,V_MATURE_DATE,V_STATUS;   
--计算需要计算的最早和最晚月份   
IF ADD_MONTHS(V_END_DATE,-24)<V_DATE_OPENED   
THEN V_START_DATE:=LAST_DAY(V_DATE_OPENED);   
ELSE V_START_DATE:=ADD_MONTHS(V_END_DATE,-23);   
END IF;   EXIT WHEN OVERDUE_CURSOR%NOTFOUND;   
LOOP   
EXIT WHEN V_END_DATE <= V_START_DATE;   
--计算前23个月的还款状态   
SELECT NVL(MAX(BILLING_DATE),LAST_DAY(V_START_DATE))   
INTO V_BILLING_DATE1   
FROM CL_VALID_BALANCE B   
WHERE OP_NUM=V_OP_NUM AND LAST_DAY(BILLING_DATE)=LAST_DAY(V_START_DATE);
SELECT NVL(MAX(BILLING_DATE),LAST_DAY(ADD_MONTHS(V_START_DATE,-1)))   
INTO V_BILLING_DATE2   
FROM CL_VALID_BALANCE B   
WHERE OP_NUM=V_OP_NUM AND LAST_DAY(BILLING_DATE)=LAST_DAY(ADD_MONTHS(V_START_DATE,-1));   
SELECT COUNT(*)   
INTO V_COUNT   
FROM CL_VALID_BALANCE   
WHERE OP_NUM=V_OP_NUM   
AND BILLING_DATE BETWEEN V_BILLING_DATE2+1 AND V_BILLING_DATE1;   
SELECT NVL(MAX(V_BILLING_DATE1-BILLING_DATE+1),-1)   
INTO V_COUNT1   
FROM CL_VALID_OVERDUE   
WHERE OP_NUM=V_OP_NUM AND V_BILLING_DATE1 BETWEEN BILLING_DATE AND ACTUAL_DATE-1;   
IF V_COUNT=0 AND V_COUNT1<=0 THEN V_24MONTHS_FLAG:=CONCAT(V_24MONTHS_FLAG,'*');   
ELSIF V_COUNT1<=0 THEN V_24MONTHS_FLAG:=CONCAT(V_24MONTHS_FLAG,'N');   
ELSIF TRUNC((V_COUNT1-1)/30+1)<8 THEN V_24MONTHS_FLAG:=CONCAT(V_24MONTHS_FLAG,TRUNC((V_COUNT1-1)/30+1));   
ELSE V_24MONTHS_FLAG:=CONCAT(V_24MONTHS_FLAG,'7');   
END IF;   
V_START_DATE:=ADD_MONTHS(V_START_DATE,1);   
END LOOP;   
--计算最后一个月的还款状态   
SELECT NVL(MAX(BILLING_DATE),LAST_DAY(V_START_DATE))   
INTO V_BILLING_DATE1   
FROM CL_VALID_BALANCE B   
WHERE OP_NUM=V_OP_NUM AND LAST_DAY(BILLING_DATE)=LAST_DAY(V_START_DATE);   
SELECT NVL(MAX(BILLING_DATE),LAST_DAY(ADD_MONTHS(V_START_DATE,-1)))   
INTO V_BILLING_DATE2   
FROM CL_VALID_BALANCE B   
WHERE OP_NUM=V_OP_NUM AND LAST_DAY(BILLING_DATE)=LAST_DAY(ADD_MONTHS(V_START_DATE,-1));   
SELECT COUNT(*)   
INTO V_COUNT   
FROM CL_VALID_BALANCE   
WHERE OP_NUM=V_OP_NUM   
AND BILLING_DATE BETWEEN V_BILLING_DATE2+1 AND V_BILLING_DATE1;   
SELECT NVL(MAX(V_BILLING_DATE1-BILLING_DATE+1),-1)   
INTO V_COUNT1   
FROM CL_VALID_OVERDUE   
WHERE OP_NUM=V_OP_NUM AND V_BILLING_DATE1 BETWEEN BILLING_DATE AND ACTUAL_DATE-1;   
IF V_STATUS='9'   
THEN V_24MONTHS_FLAG:=CONCAT(V_24MONTHS_FLAG,'C');   
ELSIF V_COUNT=0 AND V_COUNT1<=0 THEN V_24MONTHS_FLAG:=CONCAT(V_24MONTHS_FLAG,'*');   
ELSIF V_COUNT1<=0 THEN V_24MONTHS_FLAG:=CONCAT(V_24MONTHS_FLAG,'N');   
ELSIF TRUNC((V_COUNT1-1)/30+1)<8 THEN V_24MONTHS_FLAG:=CONCAT(V_24MONTHS_FLAG,TRUNC((V_COUNT1-1)/30+1));   
ELSE V_24MONTHS_FLAG:=CONCAT(V_24MONTHS_FLAG,'7');   
END IF;   
INSERT INTO CL_MONTHS24_STATUS_TOTAL VALUES (V_OP_NUM,LPAD(V_24MONTHS_FLAG,24,'/'));   
COMMIT;   
END LOOP;   
--关闭游标   
CLOSE OVERDUE_CURSOR;   
--程序体结束   
END;   
--存储过程结束   
END;

存储过程专题(Oracle)的更多相关文章

  1. 高品质开源工具Chloe.ORM:支持存储过程与Oracle

    扯淡 这是一款高质量的.NET C#数据库访问框架(ORM).查询接口借鉴 Linq.借助 lambda 表达式,可以完全用面向对象的方式就能轻松执行多表连接查询.分组查询.聚合查询.插入数据.批量删 ...

  2. mssql sqlserver存储过程专题

    MSSQL存储过程简介及创建方式 mssql_DB_存储过程类型简介   MSSQL sql存储过程创建简介及应用举例 MSSQL SQl server 2008 CLR 存储过程创建举例 MSSQL ...

  3. 数据库_存储过程简介(oracle版)

    应朋友要求,写个存储过程说明,本篇比较简单,适合新接触存储过程的同学 先来个简单的 begin dbms_output.put_line('my first execute'); end; 如果使用的 ...

  4. [转]高品质开源工具Chloe.ORM:支持存储过程与Oracle

    本文转自:http://www.cnblogs.com/so9527/p/6131177.html 扯淡 这是一款高质量的.NET C#数据库访问框架(ORM).查询接口借鉴 Linq.借助 lamb ...

  5. Oracle SQL Developer 调试存储过程步骤(Oracle)

    1.首先你编译通过你的存储过程,编译的时候一定要选“编译以进行调试”. 2.在想要调试的行上设置好断点. 3.点击“调试”按钮,然后输入存储过程入参,点“确定”开始调试. 4.断点进入后,上方会出现一 ...

  6. 编写存储过程导出oracle表数据到多个文本文件

    1.测试表和数据: create table test(id )); begin .. loop insert into test values(k,'test'||k); end loop; end ...

  7. 使用存储过程将Oracle数据批量导出为多个csv文件

    数据库有如下表结构: user_info (   user_id           NUMBER primary key,   user_name     VARCHAR2(200) NOT NUL ...

  8. Oracle job procedure 存储过程定时任务

    Oracle job procedure 存储过程定时任务 oracle job有定时执行的功能,可以在指定的时间点或每天的某个时间点自行执行任务. 一.查询系统中的job,可以查询视图 --相关视图 ...

  9. MySQL与Oracle 差异比较之五存储过程&Function

    存储过程&Function 编号 类别 ORACLE MYSQL 注释 1 创建存储过程语句不同 create or replace procedure P_ADD_FAC(   id_fac ...

  10. Oracle之存储过程

    1.存储过程创建 oracle中创建存储过程的语法如下: CREATE [OR REPLACE] PROCEDURE PRO_NAME[(parameter1[,parameter2]...)]is| ...

随机推荐

  1. 优秀的 Java 程序员所应该知道的 Java 知识

    JDK 相关知识 JDK 的使用 JDK 源代码 JDK 相应技术背后的原理 JVM 相关知识 服务器端开发需要重点熟悉的 Java 技术 Java 并发 Java IO 开源框架 Java 之外的知 ...

  2. 分布式对象存储之FDFS

    1.它是一个开源的分布式文件系统,它对文件进行管理. 功能有:文件存储.文件同步.文件访问(文件的上传下载)等.特别适合以文件为主的在线服务. 2.fastDFS服务端有两个角色:跟踪器(tracke ...

  3. Docker之基础(一)

    接触Docker有很久一段时间, 但是没有好好总结一下, 借此公司项目全面容器化, 记录一下常用的Docker操作 概况: 本次容器化的项目包括PHP+Python项目,PHP是基于php-fpm的基 ...

  4. 序列化-serialVersionUID作用

    Serializable接口 作用:标记一个类可以被序列化,如果没有实现该接口,则会抛出异常. ObjectOutputStream中源码: 实验: serialVersionUID 作用:表示一个序 ...

  5. web移动端常见问题(一)

    1.1物理像素 产生原因:css样式的最小值是1px,不过这个1px只是代表css像素,在高清屏上展示的物理像素要>1(iphone6 1css像素=2物理像素.而iph6p则是1css像素=3 ...

  6. 记录一次C#爬虫记录,获取必应图片

    记录一次C#爬虫记录,获取必应图片 起因 事情是这样的,我创建了一个仓库,里面有2018年到目前为止每日的必应壁纸,在八月份的时候我看到微软有接口文档,于是写了一个服务,每天早上八点钟会获取必应壁纸( ...

  7. uni-app小程序项目使用iconfont字体图标

    前情 uni-app是我比较喜欢的跨平台框架,它能开发小程序/H5/APP(安卓/iOS),重要的是对前端开发友好,自带的IDE让开发体验非常棒,公司项目就是主推uni-app. 为什么要这么做? 借 ...

  8. Ant Design Pro项目ProTable怎么获取搜索表单值

    前情 公司有经常需要做一些后台管理页面,我们选择了Ant Design Pro,它是基于 Ant Design 和 umi 的封装的一整套企业级中后台前端/设计解决方案. 产品效果图 最新接到的一个后 ...

  9. COSBrowser 移动端——随时随地查看管理数据

    外出身边没有电脑,需要查看管理数据怎么办? 出现紧急情况,需要快速停止某个 bucket 对外访问,怎么办? 个人用户仅作为网盘使用,需要方便轻量的管理工具,怎么办? 不用着急,COSBrowser ...

  10. 使用 Windows Debugger 调试托管代码

    使用 Windows Debugger 调试托管代码 https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugg ...