本文转自 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. linux bash shell 中的单引号和双引号

    摘抄自:ABS_CN 当要引用一个变量的值时,一般推荐使用双引号.使用双引号除了变量名[2]前缀($).后引符(`)和转义符(\)外,会使shell不再解释引号中其它所有的特殊字符.[3] 用双引号时 ...

  2. python之environs

    下面推荐一个 environs 库,利用它我们可以轻松地设置各种类型的环境变量. 安装: pip3 install environs 好,安装之后,我们再来体验一下使用 environs 来设置环境变 ...

  3. 【解决方案】Error running,Command line is too long

    一.现象 IDEA 提示 Error running,Command line is too long 二.原因 Java 命令行启动举例如下图,当命令行字符过多的时候,就会出现 Error runn ...

  4. 使用 SemanticKernel 对接 Ollma

    前面的 2 篇文章已经介绍了 ollama 的基本情况.我们也已经能在本地跟 LLM 进行聊天了.但是如何使用代码跟 LLM 进行交互呢?如果是 C# 选手那自然是使用 SK (SemanticKer ...

  5. manim边做边学--文字的创建与销毁

    本篇开始介绍Manim中的动画模块,动画模块是整个框架的核心魅力所在. Manim不仅提供了可以直接实现各种各样动画效果的对象, 还提供了设置动画的时长.延迟时间以及运动速率等参数,可以据此发挥自己的 ...

  6. 中电金信多模态鉴伪技术抵御AI造假威胁

    ​ AI换脸技术,属于深度伪造最常见方式之一,是一种利用人工智能生成逼真的虚假人脸图片或视频的技术.基于深度学习算法,可以将一个人的面部特征映射到另一个人的面部,创造出看似真实的伪造内容.近年来,以A ...

  7. 搭建 zerotier 的行星服务

    放弃moon节点,直接搭建Zerotier根服务器_软件应用_什么值得买 Zerotier的优点在于其部署十分简便,只需在zerotier官网注册登陆并创建网络,在自己的设备安装客户端加入网络后,ze ...

  8. 2019.12.10笔记——Spring Boot热部署的使用和实现自己的热部署(类加载器相关)

    Spring Boot热部署 热部署的使用 引入依赖 <!-- spring boot热部署的依赖 --> <dependency> <groupId>org.sp ...

  9. ssh远程执行命令方法和Shell脚本实例

    写这篇博客之前,我google了一堆相关文章,大都是说修改/etc/sudoers,然后NOPASSWD:指定的cmd,但是真心不管用,没有远程虚拟终端这个方法就是浮云,ubuntu10.04 ser ...

  10. [转]spring-framework-x.x.x.RELEASE-dist下载教程

    原文链接: spring-framework-x.x.x.RELEASE-dist下载教程