当应用有调用存储过程,而节点有几十个或者上百个,找错是不是一个很麻烦的事情,这个时候,我建议写到数据库中,下面是我做的一个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语句差异的更多相关文章

  1. 存储过程系列之调试存储过程 SQL Server 2005

    在数据库中直接调试  在数据库中直接调试是调试SQL Server 2005的存储过程的最简单的方法. 在Visual Stuido的IDE中你可以选择单步执行存储过程,然后就可以一条语句一条语句地单 ...

  2. Oracle,SQL Server 数据库较MySql数据库,Sql语句差异

    原文:Oracle,SQL Server 数据库较MySql数据库,Sql语句差异 Oracle,SQL Server 数据库较MySql数据库,Sql语句差异 1.关系型数据库 百度百科 关系数据库 ...

  3. Mysql调试存储过程最简单的方法

    以前同事告诉我用临时表插入变量数据来查看,但是这种方法过于麻烦,而且Mysql没有比较好的调试存储过程的工具.今天google了下发现可以用select + 变量名的方法来调试...真是让我汗颜啊. ...

  4. PLSQL Developer调试 存储过程和触发器

    1. 打开PL/SQL Developer如果 在机器上安装了PL/SQL Developer的话,打开PL/SQL Developer界面输入 用户名,密码和host名字,这个跟在程序中web.co ...

  5. ORACLE-Kill 杀死正在执行的Oracle存储过程和死锁语句

    ORACLE-Kill 杀死正在执行的Oracle存储过程和死锁语句 存储过程 1.找到正在执行的存储过程的 sid ,serial# select   b.sid,b.SERIAL#,a.OBJEC ...

  6. 存储过程与SQL语句如何选择

    58到家数据库30条军规,有一条是“禁止使用存储过程.视图.触发器.Event”, 高并发大数据的互联网业务,架构设计思路是“解放数据库CPU,将计算转移到服务层”, 并发量大的情况下,这些功能很可能 ...

  7. 如何oracle调试存储过程

    1.打开PL/SQL Developer 如果在机器上安装了PL/SQL Developer的话,打开PL/SQL Developer界面 输入用户名,密码和host名字,这个跟在程序中web.con ...

  8. 使用 declare 语句和strict_types 声明来启用严格模式:

    使用 declare 语句和strict_types 声明来启用严格模式: Caution: 启用严格模式同时也会影响返回值类型声明. Note: 严格类型适用于在启用严格模式的文件内的函数调用,而不 ...

  9. plsql调试存储过程卡住的原因以及处理

    用PLSQL调试存储过程的时候,经常会遇到这个的情况,点调试后,继续点单步都是灰色,想停下来,但是取消也要点很多次才能取消掉. 就像下面的情况: 一直以为是个BUG,直到最近有人告诉我了真相. 出现这 ...

随机推荐

  1. struts2-convention-plugin零配置

    零配置的意思并不是说没有配置,而是通过约定大于配置的方式,大量通过约定来调度页面的跳转而使得配置大大减少. <?xml version="1.0" encoding=&quo ...

  2. 字符串dp——牛客多校第五场G

    比赛的时候脑瘫了没想出来..打多校以来最自闭的一场 显然从s中选择大于m个数组成的数必然比t大,所以只要dp求出从s中选择m个数大于t的方案数 官方题解是反着往前推,想了下反着推的确简单,因为高位的数 ...

  3. NX二次开发-创建直线UF_CURVE_create_line与NXOpen->CreateLine

    NX11+VS2013 #include <uf.h> #include <uf_curve.h> #include <NXOpen/CurveCollection.hx ...

  4. NX二次开发-将对象移动到图层UF_OBJ_set_layer

    #include <uf.h> #include <uf_obj.h> #include <uf_modl.h> #include <uf_layer.h&g ...

  5. C语言进阶学习第三章

    以下记录动态内存分配: 1.malloc和free malloc和free分别用于执行动态内存分配和释放.这些函数维护一个可用内存池,当一个程序需要一些内存时,调用malloc函数,malloc从内存 ...

  6. HDU 2167 状压dp方格取数

    题意:给出一个数表,规定取出一个数后周围的八个数都不可取,求可获得的最大数字和 思路:状态压缩dp,每一行的取数方法为状态,显然,由于取数规则的限制,可取的状态并不是 1<<size_co ...

  7. 通过快递100获取快递单号,结合c-lodop热敏纸打印 – 通过菜鸟ISV/自研ERP使用菜鸟电子面单

    https://www.1024cc.cn/index.php/2019/04/29/%E6%89%93%E5%8D%B0%E7%94%B5%E5%AD%90%E9%9D%A2%E5%8D%95/ 打 ...

  8. ARM多核处理器启动过程分析

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/qianlong4526888/article/details/27695173 说明: 该流程图依照 ...

  9. 解决OCX 在 非开发电脑上注册出错的问题

    这几天遇到一个问题,就是在我自己电脑上开发的OCX 放在其他电脑上居然注册失败,管理员运行也不行,老是会蹦出这样的错误,最后呢终于让我找到一个线索就是在开发电脑上可以安装,在无开发环境上很大概率安装失 ...

  10. 错误Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/fs/FSDataInputStream排查思路

    spark1(默认CDH自带版本)不存在这个问题,主要是升级了spark2(CDHparcel升级)版本安装后需要依赖到spark1的旧配置去读取hadoop集群的依赖包. 1./etc/spark2 ...