
-----正文-----

本文就DM存储过程问题的排查方法进行简单介绍,主要针对打印错误代码信息和存储过程SQL耗时长的定位方法进行测试验证。
本章内容已在如下环境上测试:
操作系统:银河麒麟V10
数据库:DM8
相关关键字:DM8,存储过程
在DM数据库存储过程的调试执行过程中,会遇到异常错误无法准确定位的问题,这就造成无法及时准确地对错误进行修改。有没有方法来快速来定位错误的原因呢?答案是肯定的,本文通过实例进行测试,供大家参考使用。
1.1、 创建字段类型为数据类型的表
CREATE TABLE "TEST"."DMTEST01" ("ID" INT) ;
1.2、创建异常记录日志表
CREATE TABLE "TEST"."T_PROC_ERRMSG"("SQLCODE" VARCHAR(50) ,"SQLERRM" VARCHAR(200),"EXECDATE" DATETIME(6));
1.3、 存储过程应用示例
create or replaceprocedure test.pr_error_code_test(TEST in varchar2)isdeclare begininsert into TEST.DMTEST01(id) values(TEST);commit;--异常错误记录处理exceptionwhen others theninsert into TEST.T_PROC_ERRMSG values( sqlcode, sqlerrm, SYSDATE);print sqlcode;print sqlerrm;commit;return;end;/
1.4、执行存储过程(将参数设置为字符串)
call "TEST"."PR_ERROR_CODE_TEST"('a');
1.5、查看异常记录信息
select * from "TEST"."T_PROC_ERRMSG";

通过以上方法可以定位到存储过程的错误信息。
存储过程的调试一直很令人头疼,因为里面的动态 SQL 和程序逻辑让人很难上手,所以我们建议他们将 EXECUTE IMMEDIATE 做一次分装,即把执行 SQL 的函数进行封装,函数里记录上我们需要的信息。
2.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.2、创建存储过程方法
CREATE OR REPLACEPROCEDURE EXECSQL(I_SQLSTRING IN VARCHAR2)ASV_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);BEGINV_TIME :=SYSDATE;V_CURTIME :=DBMS_UTILITY.GET_TIME;V_SQLSTRING :=TRIM(I_SQLSTRING);--去除SQL语句多余的空格WHILE INSTR(V_SQLSTRING, ' ')>0LOOPV_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 THENV_SQL :=TRIM(SUBSTRB(V_SQLSTRING, 1, 4000));V_SID := SYS_CONTEXT('USERENV', 'SID');V_CALL_STACK:=DBMS_UTILITY.FORMAT_CALL_STACK;INSERTINTOSQL_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;
2.3、创建存储过程测试方法
CREATE OR REPLACEPROCEDURE "TEST"."PR_ERROR_CODE_TEST" AUTHID DEFINERisdeclarebegincall "TEST"."EXECSQL"('delete from "TEST"."DMTEST01" where id>10;');exceptionwhen others theninsert into TEST.T_PROC_ERRMSG values( sqlcode, sqlerrm, SYSDATE);print sqlcode;print sqlerrm;commit;end;
2.4、执行测试
call "TEST"."PR_ERROR_CODE_TEST"();
2.5、结果展示
执行后的记录结果:

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

EXECSQL:表示调用EXECSQL方法的第29行。
PR_ERROR_CODE_TEST:表示该存储过程中第7行SQL语句。
通过以上的方法我们就可以清楚的定位到具体执行的 SQL 和 SQL 执行耗时。
>>> THE END <<<
相关推荐

文章转载自达梦E学,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




