本文转自 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. nano编辑器保存退出

    nano的编辑器保存推出 使用 ctrl x 然后提示Y N 是否保存 写入,输入Y即可 然后再Enter 确认就可以了

  2. 用于自然语言处理的循环神经网络RNN

    前一篇:<人工智能模型学习到的知识是怎样的一种存在?> 序言:在人工智能领域,卷积神经网络(CNN)备受瞩目,但神经网络的种类远不止于此.实际上,不同类型的神经网络各有其独特的应用场景.在 ...

  3. 从InputStream到ByteArrayInputStream

    本篇主要分析:1.如何将byte数组适配至ByteArrayInputStream,对应与IO部分的适配器模式:2.BufferedInputStream的工作原理,对应于IO的装饰器模式,会首先研究 ...

  4. python多版本管理软件pyenv

    我们在平时的项目开发或者学习中,有可能使用不同的Python版本,大家都知道Python的版本非常多,如果我们把需要的不同版本的Python都下载到服务器上,管理起来会非常困难,多版本并存又容易互相干 ...

  5. Spring Data JPA自动生成表时列顺序混乱的解决办法(最新版)

    最近把Spring Boot的版本升级到了3.3.5,突然发现一个问题:当使用Spring Data JPA自动生成表的时候,所产生的列顺序与Entity类中的变量顺序不一致了.比如,有一个下面这样的 ...

  6. 第四届河南省 CCPC 大学生程序设计竞赛

    F-集合之和 规定集合A和集合B的加法运算:\(A+B={x+y|x∈A,y∈B}\),设有限数集A中的元素个数为|A|,现给定n,请你构造集合A使得\(|A+A|=n\),如果A不存在,输出-1 题 ...

  7. Mybatis【18】-- Mybatis自关联多对一查询方式

    注:代码已托管在GitHub上,地址是:https://github.com/Damaer/Mybatis-Learning ,项目是mybatis-14-oneself-many2one,需要自取, ...

  8. 表里不一--限制容器内存4G,free还是32G

    前言 最近有个新同事问了我一个问题,明明通过limit给容器内存限制了4G,为什么进容器看到的还是宿主机的内存32G docker run -it --rm -m 512m ubuntu:18.04 ...

  9. 使用C#获取文件详情

    有对应的需求,需要获取文件的详细信息内容.该页面信息大部分来源于文件的版本信息,使用FileInfo类并不能获取到. VERSIONINFO 资源 - Win32 apps | Microsoft L ...

  10. uni-app小程序(快手)日志打印坑位记录

    前情 uni-app是我比较喜欢的跨平台框架,它能开发小程序/H5/APP(安卓/iOS),重要的是对前端开发友好,自带的IDE让开发体验也挺棒的,公司项目就是主推uni-app. 坑位 最近在开发一 ...