DM存储过程打印错误代码信息和存储过程SQL耗时长的定位方法

目录

一、DM存储过程打印错误代码信息

1.创建字段类型为数据类型的表

2.创建异常记录日志表

3.存储过程应用示例 

4.执行存储过程(将参数设置为字符串)

5.查看异常记录信息

二、DM存储过程SQL耗时长的定位方法

1、创建日志记录信息表

2、创建存储过程方法

3、创建存储过程测试方法

4、执行测试

5、结果展示


本文就DM存储过程问题的排查方法进行简单介绍,主要针对打印错误代码信息和存储过程SQL耗时长的定位方法进行测试验证。

验证环境如下表:

软件版本
操作系统银河麒麟V10
DM 数据库DM8-1-2-18-21.06.24-142387-10013-ENT Pack4
CPU 架构x86

一、DM存储过程打印错误代码信息

在DM数据库存储过程的调试执行过程中,会遇到异常错误无法准确定位的问题,这就造成无法及时准确地对错误进行修改。那有没有方法来快速来定位错误的原因呢?答案是肯定的,本文通过实例进行测试,供大家参考使用。

1.创建字段类型为数据类型的表

CREATE TABLE "TEST"."DMTEST01" ("ID" INT) ;

2.创建异常记录日志表

CREATE TABLE "TEST"."T_PROC_ERRMSG"
(
"SQLCODE" VARCHAR(50),
"SQLERRM" VARCHAR(200),
"EXECDATE" DATETIME(6)) ;

3.存储过程应用示例 

create or replace procedure test.pr_error_code_test(TEST in varchar2)
is
 declare
 begin
    insert into  TEST.DMTEST01 (id) values(TEST);
 commit;
--异常错误记录处理
 exception 
   when others then
     insert into TEST.T_PROC_ERRMSG values( sqlcode , sqlerrm ,SYSDATE);
     dbms_output.put_line(sqlcode);
     dbms_output.put_line(sqlerrm);
     commit;
      return;
 end;
 /

4.执行存储过程(将参数设置为字符串)

 call "TEST"."PR_ERROR_CODE_TEST"('a');

5.查看异常记录信息

 select * from "TEST"."T_PROC_ERRMSG";

 通过以上方法可以定位到存储过程的错误信息。


二、DM存储过程SQL耗时长的定位方法

存储过程的调试一直很令人头疼,因为里面的动态 SQL 和程序逻辑让人很难上手,所以我们建议他们将 EXECUTE IMMEDIATE 做一次分装,即把执行 SQL 的函数进行封装,函数里记录上我们需要的信息。

1、创建日志记录信息表

CREATE TABLE TEST.SQL_TRACE

(

LOG_NO INT IDENTITY(1, 1),

USER_NAME VARCHAR ,

BEGIN_TIME DATE ,

END_TIME DATE ,

SQL_STR VARCHAR ,

ROW_COUNT INT ,

SESSION_ID BIGINT ,

IP_ADDRESS VARCHAR ,

CALL_STACK VARCHAR ,

TIMES INT

);

2、创建存储过程方法

CREATE OR REPLACE PROCEDURE EXECSQL(I_SQLSTRING IN VARCHAR2)

AS

V_ROWNUMID INTEGER;

V_TIME DATE;

V_SQLSTRING VARCHAR2(32767);

V_SQL VARCHAR2(8188);

V_CURTIME NUMBER(20, 2);

V_USETIME NUMBER(20, 2);

V_SID NUMBER(30);

V_SES V$SESSIONS%ROWTYPE;

V_CALL_STACK VARCHAR2(4000);

BEGIN

V_TIME :=SYSDATE;

V_CURTIME :=DBMS_UTILITY.GET_TIME;

V_SQLSTRING:=TRIM(I_SQLSTRING);

--去除SQL语句多余的空格

WHILE INSTR(V_SQLSTRING, ' ')>0

LOOP

V_SQLSTRING:=REPLACE(V_SQLSTRING, ' ', ' ');

END LOOP;

--执行SQL语句

EXECUTE IMMEDIATE V_SQLSTRING;

V_ROWNUMID:=SQL%ROWCOUNT;

V_USETIME :=(DBMS_UTILITY.GET_TIME-V_CURTIME)/100;

--运行时间超过0.5秒,记录语句日志

IF V_USETIME >=0.5 THEN

V_SQL :=TRIM(SUBSTRB(V_SQLSTRING, 1, 4000));

V_SID := SYS_CONTEXT('USERENV','SID');

V_CALL_STACK:=DBMS_UTILITY.FORMAT_CALL_STACK;

INSERT

INTO

SQL_TRACE

(

USER_NAME ,

BEGIN_TIME,

END_TIME ,

SQL_STR ,

ROW_COUNT ,

SESSION_ID,

IP_ADDRESS,

CALL_STACK,

TIMES

)

VALUES

(

SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA'),

V_TIME ,

SYSDATE ,

V_SQL ,

V_ROWNUMID ,

V_SID ,

SYS_CONTEXT('USERENV', 'IP_ADDRESS') ,

V_CALL_STACK ,

V_USETIME

);

commit;

END IF;

END EXECSQL;

3、创建存储过程测试方法

CREATE OR REPLACE PROCEDURE "TEST"."PR_ERROR_CODE_TEST"

AUTHID DEFINER

is

declare

begin

call "TEST"."EXECSQL"('delete from "TEST"."DMTEST01" where id>10;');

exception

when others then

insert into TEST.T_PROC_ERRMSG values( sqlcode , sqlerrm ,SYSDATE);

dbms_output.put_line(sqlcode);

dbms_output.put_line(sqlerrm);

commit;

end;

4、执行测试

call "TEST"."PR_ERROR_CODE_TEST"();

5、结果展示

执行后的记录结果:

表中记录了登录用户、开始时间、结束时间、影响行数、SESSID、IP 和存储过程的 TRACE BACK,里面记录了查询发生在哪个存储过程的哪一行:

 EXECSQL:表示调用EXECSQL方法的第29行。

PR_ERROR_CODE_TEST:表示该存储过程中第7行SQL语句。

通过以上的方法我们就可以清楚的定位到具体执行的 SQL 和 SQL 执行耗时。

 感谢同事的支持!!!

更多资讯请上达梦技术社区了解:达梦数据库 - 新一代大型通用关系型数据库 | 达梦云适配中心https://eco.dameng.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值