调试存储过程与declare语句差异
当应用有调用存储过程,而节点有几十个或者上百个,找错是不是一个很麻烦的事情,这个时候,我建议写到数据库中,下面是我做的一个demo.
1、 建立错误日志记录表
drop table PUB_PROC_ERR_LOG purge;
create table PUB_PROC_ERR_LOG
(
LOG_ID NUMBER,
MODULE_NAME VARCHAR2(100),
PROC_NAME VARCHAR2(100),
ERR_TIME DATE,
SQL_CODE VARCHAR2(50),
SQL_ERRM VARCHAR2(100),
ERR_CONTENT VARCHAR2(500)
);
comment on column PUB_PROC_ERR_LOG.LOG_ID is '主键';
comment on column PUB_PROC_ERR_LOG.MODULE_NAME is '模块名称';
comment on column PUB_PROC_ERR_LOG.PROC_NAME is '存储过程名称';
comment on column PUB_PROC_ERR_LOG.ERR_TIME is '报错时间';
comment on column PUB_PROC_ERR_LOG.SQL_CODE is 'SQLCODE';
comment on column PUB_PROC_ERR_LOG.SQL_ERRM is 'SQLERRM';
comment on column PUB_PROC_ERR_LOG.ERR_CONTENT is '报错的具体行';
2、表主键的序列
create sequence SEQ_RECORD_PROC_ERR
minvalue 1
maxvalue 9999999999999999999999999999
start with 21
increment by 1 cache 20;
3、通用记录错误存储过程,用自治事务
CREATE OR REPLACE PROCEDURE
record_proc_err_log(module_name varchar2,
proc_name varchar2,
v_SQLCODE varchar2,
v_SQLERRM varchar2,
v_err_line varchar2) is
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
insert into pub_proc_err_log
(log_id,
module_name,
proc_name,
err_time,
sql_code,
sql_errm,
err_content)
values
(seq_record_proc_err.nextval,
module_name,
proc_name,
sysdate,
v_SQLCODE,
v_SQLERRM,
v_err_line);
commit;
END record_proc_err_log;
4、测试
create or replace procedure proce_test is
begin
for rec in (SELECT T1.*
FROM XX.V_PROD_INST_INFO T1, AUDI_SAMPLE_NM T2
where t1.PROD_INST_ID = t2.prod_inst_id) loop
begin
INSERT INTO ASA_PROD_INFO_PROV_NM_BK
(PROV_CODE,
PROD_INST_ID,
PROD_ID,
EXT_PROD_ID,
ACC_NUM,
ACCOUNT,
PAYMENT_MODE_CD,
OWNER_CUST_ID,
STATUS_CD,
AUDI_DATE,
AUDI_BATCH)
values
('NM',
rec.PROD_INST_ID,
rec.PROD_ID,
rec.EXT_PROD_ID,
rec.ACC_NUM,
rec.ACCOUNT,
rec.PAYMENT_MODE_CD,
rec.OWNER_CUST_ID,
rec.STATUS_CD,
sysdate,
'2017-12');
commit;
Exception
WHEN OTHERS
Then
record_proc_err_log('moduleName',
'proce_test()',
SQLCODE,
SQLERRM,
substr(dbms_utility.format_error_backtrace,1,400));
end;
end loop;
end proce_test;
5、编译存过 调试存过,输入参数,点击放大镜(开始调试器)开始debug存过


6、执行存过(如下两种方式):


等价于如下存过/语句块,给表里面插入数据,并显示错误信息。此种方式记录的错误信息在语句执行结束后在输出窗口显示
create or replace procedure proce_test is
--is下面为变量声明区域
iStep number;
iCount number;
begin
--变量初始化区域
iStep := 0;
iCount := 0;
<<outer_loop>> for rec in (SELECT T1.*
FROM XX.V_PROD_INST_INFO T1, AUDI_SAMPLE_NM T2
where t1.PROD_INST_ID = t2.prod_inst_id) loop
begin
INSERT INTO ASA_PROD_INFO_PROV_NM_BK
(PROV_CODE,
PROD_INST_ID,
PROD_ID,
EXT_PROD_ID,
ACC_NUM,
ACCOUNT,
PAYMENT_MODE_CD,
OWNER_CUST_ID,
STATUS_CD,
AUDI_DATE,
AUDI_BATCH)
values
('NM',
rec.PROD_INST_ID,
rec.PROD_ID,
rec.EXT_PROD_ID,
rec.ACC_NUM,
rec.ACCOUNT,
rec.PAYMENT_MODE_CD,
rec.OWNER_CUST_ID,
rec.STATUS_CD,
sysdate,
'2017-12');
commit;
Exception
WHEN OTHERS
Then
record_proc_err_log('moduleName',
'proce_test()',
SQLCODE,
SQLERRM,
substr(dbms_utility.format_error_backtrace,1,400));
end;
exit outer_loop;
iStep := iStep + 1;
iCount := iCount + 1;
if iStep = 2000 then
iStep := 0;
insert into CS_COUNT_LOG values ('CP', sysdate, iCount);
commit;
end if;
end loop;
insert into CS_COUNT_LOG values ('CP', sysdate, iCount);
commit;
end;
end proce_test;
declare
iStep number;
iCount number;
sErrstr varchar2(1024);
begin
iStep := 0;
iCount := 0;
<<outer_loop>>
for rec in (SELECT T1.*
FROM DC_ALL_NM.V_PROD_INST_INFO T1, AUDI_SAMPLE_NM T2
where t1.PROD_INST_ID = t2.prod_inst_id) loop
begin
INSERT INTO ASA_PROD_INFO_PROV_NM_BK
(PROV_CODE,
PROD_INST_ID,
PROD_ID,
EXT_PROD_ID,
ACC_NUM,
ACCOUNT,
PAYMENT_MODE_CD,
OWNER_CUST_ID,
STATUS_CD,
AUDI_DATE,
AUDI_BATCH)
values
('NM',
rec.PROD_INST_ID,
rec.PROD_ID,
rec.EXT_PROD_ID,
rec.ACC_NUM,
rec.ACCOUNT,
rec.PAYMENT_MODE_CD,
rec.OWNER_CUST_ID,
rec.STATUS_CD,
sysdate,
'2017-12');
exception
when others then
sErrstr := '写表 xxxxxx 出错SQL:' || rec.PROD_INST_ID ||
rec.PAYMENT_MODE_CD || rec.PROD_ID || rec.EXT_PROD_ID ||
rec.OWNER_CUST_ID || ',SQL??:' || SQLCODE || ',' ||
Sqlerrm || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
exit outer_loop;
return;
end;
iStep := iStep + 1;
iCount := iCount + 1;
if iStep = 2000 then
iStep := 0;
insert into CS_COUNT_LOG values ('CP', sysdate, iCount);
commit;
end if;
end loop;
dbms_output.put_line(sErrstr);
insert into CS_COUNT_LOG values ('CP', sysdate, iCount);
commit;
end;
/

调试存储过程与declare语句差异的更多相关文章
- 存储过程系列之调试存储过程 SQL Server 2005
在数据库中直接调试 在数据库中直接调试是调试SQL Server 2005的存储过程的最简单的方法. 在Visual Stuido的IDE中你可以选择单步执行存储过程,然后就可以一条语句一条语句地单 ...
- Oracle,SQL Server 数据库较MySql数据库,Sql语句差异
原文:Oracle,SQL Server 数据库较MySql数据库,Sql语句差异 Oracle,SQL Server 数据库较MySql数据库,Sql语句差异 1.关系型数据库 百度百科 关系数据库 ...
- Mysql调试存储过程最简单的方法
以前同事告诉我用临时表插入变量数据来查看,但是这种方法过于麻烦,而且Mysql没有比较好的调试存储过程的工具.今天google了下发现可以用select + 变量名的方法来调试...真是让我汗颜啊. ...
- PLSQL Developer调试 存储过程和触发器
1. 打开PL/SQL Developer如果 在机器上安装了PL/SQL Developer的话,打开PL/SQL Developer界面输入 用户名,密码和host名字,这个跟在程序中web.co ...
- ORACLE-Kill 杀死正在执行的Oracle存储过程和死锁语句
ORACLE-Kill 杀死正在执行的Oracle存储过程和死锁语句 存储过程 1.找到正在执行的存储过程的 sid ,serial# select b.sid,b.SERIAL#,a.OBJEC ...
- 存储过程与SQL语句如何选择
58到家数据库30条军规,有一条是“禁止使用存储过程.视图.触发器.Event”, 高并发大数据的互联网业务,架构设计思路是“解放数据库CPU,将计算转移到服务层”, 并发量大的情况下,这些功能很可能 ...
- 如何oracle调试存储过程
1.打开PL/SQL Developer 如果在机器上安装了PL/SQL Developer的话,打开PL/SQL Developer界面 输入用户名,密码和host名字,这个跟在程序中web.con ...
- 使用 declare 语句和strict_types 声明来启用严格模式:
使用 declare 语句和strict_types 声明来启用严格模式: Caution: 启用严格模式同时也会影响返回值类型声明. Note: 严格类型适用于在启用严格模式的文件内的函数调用,而不 ...
- plsql调试存储过程卡住的原因以及处理
用PLSQL调试存储过程的时候,经常会遇到这个的情况,点调试后,继续点单步都是灰色,想停下来,但是取消也要点很多次才能取消掉. 就像下面的情况: 一直以为是个BUG,直到最近有人告诉我了真相. 出现这 ...
随机推荐
- 58 matlab 编程
0 引言 matlab中有些东西记录一下 1 matlab coder matlab命令行窗口输入: coder 回车即可打开matlab coder 窗口.接着,matlab将引导你把matlab格 ...
- C++之判断字符串是否是数字
文章转载自https://blog.csdn.net/Richard__Ting/article/details/80772174 判断是否为数字 #include <iostream> ...
- POJ-1836-Alignment-双向LIS(最长上升子序列)(LIS+LSD)+dp
In the army, a platoon is composed by n soldiers. During the morning inspection, the soldiers are al ...
- AtCoder ABC 127F Absolute Minima
题目链接:https://atcoder.jp/contests/abc127/tasks/abc127_f 题目大意 初始状态下$f(x) = 0$,现在有 2 种模式的询问,第一种以“1 a b” ...
- postgresql+java数据类型对照
网上搜了很多都不理想,这里总结的一部分是官网的文档,一部分是网上的,大体没问题 PostgreSQL™ Java SE 8 date LocalD ...
- mysql key分区,分区数制定
我相信不 太注意的同学肯定会入坑,今天我差点也入坑了,后面自己问自己如果我用key分区,自己问自己 我的分区数应该是多少??? 后面我陷入了沉思......... 我第一次想先随便弄一个分区数,在本地 ...
- python 15 文件操作(一)
转自 http://www.cnblogs.com/BeginMan/p/3166644.html 一.文件对象 我理解的文件对象就是一个接口,通过这个接口对文件进行相关操作. <Python ...
- 面试系列38 分库分表之后,id主键如何处理?
(1)数据库自增id 这个就是说你的系统里每次得到一个id,都是往一个库的一个表里插入一条没什么业务含义的数据,然后获取一个数据库自增的一个id.拿到这个id之后再往对应的分库分表里去写入. 这个方案 ...
- Docker学习のDocker镜像
一.列出镜像 命令:docker images [optsions] [repositort] -a 标识列出所有 -f 写过滤条件 --no-trunc 不截断id -q 只显示唯一id rep ...
- 4、Docker网络访问
现在我们已经可以熟练的使用docker命令操作镜像和容器,并学会了如何进入到容器中去,那么实际的工作中,我们通常是在Docker中部署服务,我们需要在外部通过IP和端口进行访问的,那么如何访问到Doc ...