存储过程专题(Oracle)
本文转自 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)的更多相关文章
- 高品质开源工具Chloe.ORM:支持存储过程与Oracle
扯淡 这是一款高质量的.NET C#数据库访问框架(ORM).查询接口借鉴 Linq.借助 lambda 表达式,可以完全用面向对象的方式就能轻松执行多表连接查询.分组查询.聚合查询.插入数据.批量删 ...
- mssql sqlserver存储过程专题
MSSQL存储过程简介及创建方式 mssql_DB_存储过程类型简介 MSSQL sql存储过程创建简介及应用举例 MSSQL SQl server 2008 CLR 存储过程创建举例 MSSQL ...
- 数据库_存储过程简介(oracle版)
应朋友要求,写个存储过程说明,本篇比较简单,适合新接触存储过程的同学 先来个简单的 begin dbms_output.put_line('my first execute'); end; 如果使用的 ...
- [转]高品质开源工具Chloe.ORM:支持存储过程与Oracle
本文转自:http://www.cnblogs.com/so9527/p/6131177.html 扯淡 这是一款高质量的.NET C#数据库访问框架(ORM).查询接口借鉴 Linq.借助 lamb ...
- Oracle SQL Developer 调试存储过程步骤(Oracle)
1.首先你编译通过你的存储过程,编译的时候一定要选“编译以进行调试”. 2.在想要调试的行上设置好断点. 3.点击“调试”按钮,然后输入存储过程入参,点“确定”开始调试. 4.断点进入后,上方会出现一 ...
- 编写存储过程导出oracle表数据到多个文本文件
1.测试表和数据: create table test(id )); begin .. loop insert into test values(k,'test'||k); end loop; end ...
- 使用存储过程将Oracle数据批量导出为多个csv文件
数据库有如下表结构: user_info ( user_id NUMBER primary key, user_name VARCHAR2(200) NOT NUL ...
- Oracle job procedure 存储过程定时任务
Oracle job procedure 存储过程定时任务 oracle job有定时执行的功能,可以在指定的时间点或每天的某个时间点自行执行任务. 一.查询系统中的job,可以查询视图 --相关视图 ...
- MySQL与Oracle 差异比较之五存储过程&Function
存储过程&Function 编号 类别 ORACLE MYSQL 注释 1 创建存储过程语句不同 create or replace procedure P_ADD_FAC( id_fac ...
- Oracle之存储过程
1.存储过程创建 oracle中创建存储过程的语法如下: CREATE [OR REPLACE] PROCEDURE PRO_NAME[(parameter1[,parameter2]...)]is| ...
随机推荐
- 优秀的 Java 程序员所应该知道的 Java 知识
JDK 相关知识 JDK 的使用 JDK 源代码 JDK 相应技术背后的原理 JVM 相关知识 服务器端开发需要重点熟悉的 Java 技术 Java 并发 Java IO 开源框架 Java 之外的知 ...
- 分布式对象存储之FDFS
1.它是一个开源的分布式文件系统,它对文件进行管理. 功能有:文件存储.文件同步.文件访问(文件的上传下载)等.特别适合以文件为主的在线服务. 2.fastDFS服务端有两个角色:跟踪器(tracke ...
- Docker之基础(一)
接触Docker有很久一段时间, 但是没有好好总结一下, 借此公司项目全面容器化, 记录一下常用的Docker操作 概况: 本次容器化的项目包括PHP+Python项目,PHP是基于php-fpm的基 ...
- 序列化-serialVersionUID作用
Serializable接口 作用:标记一个类可以被序列化,如果没有实现该接口,则会抛出异常. ObjectOutputStream中源码: 实验: serialVersionUID 作用:表示一个序 ...
- web移动端常见问题(一)
1.1物理像素 产生原因:css样式的最小值是1px,不过这个1px只是代表css像素,在高清屏上展示的物理像素要>1(iphone6 1css像素=2物理像素.而iph6p则是1css像素=3 ...
- 记录一次C#爬虫记录,获取必应图片
记录一次C#爬虫记录,获取必应图片 起因 事情是这样的,我创建了一个仓库,里面有2018年到目前为止每日的必应壁纸,在八月份的时候我看到微软有接口文档,于是写了一个服务,每天早上八点钟会获取必应壁纸( ...
- uni-app小程序项目使用iconfont字体图标
前情 uni-app是我比较喜欢的跨平台框架,它能开发小程序/H5/APP(安卓/iOS),重要的是对前端开发友好,自带的IDE让开发体验非常棒,公司项目就是主推uni-app. 为什么要这么做? 借 ...
- Ant Design Pro项目ProTable怎么获取搜索表单值
前情 公司有经常需要做一些后台管理页面,我们选择了Ant Design Pro,它是基于 Ant Design 和 umi 的封装的一整套企业级中后台前端/设计解决方案. 产品效果图 最新接到的一个后 ...
- COSBrowser 移动端——随时随地查看管理数据
外出身边没有电脑,需要查看管理数据怎么办? 出现紧急情况,需要快速停止某个 bucket 对外访问,怎么办? 个人用户仅作为网盘使用,需要方便轻量的管理工具,怎么办? 不用着急,COSBrowser ...
- 使用 Windows Debugger 调试托管代码
使用 Windows Debugger 调试托管代码 https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugg ...