一、达梦存储过程日常调试的实用小技巧
1.1 用“流水账式打印”定位问题
很多新手刚写存储过程时,常会遇到“跑起来没结果、结果不对”的情况,这时候不用慌,给代码加几句打印语句就像记流水账,能把每一步的运行细节清清楚楚展现出来,不用再对着代码猜。举个开发时的真实例子:要做一个给员工算年终奖的存储过程,刚写完就发现市场部员工的奖金全算错了,这时候加打印日志就能快速找到问题根源。
-- 技术栈:达梦PL/SQL
CREATE OR REPLACE PROCEDURE CALC_BONUS(P_EMP_ID IN NUMBER, O_BONUS OUT NUMBER)
IS
V_SALARY NUMBER; -- 存储员工薪资
V_DEPT_ID NUMBER; -- 存储员工所属部门ID
BEGIN
-- 第一步:打印入参,确认传参正确
DBMS_OUTPUT.PUT_LINE('调试日志:当前入参员工ID = ' || P_EMP_ID);
-- 查询员工薪资和部门,打印结果确认数据库读取正常
SELECT SALARY, DEPT_ID INTO V_SALARY, V_DEPT_ID
FROM EMPLOYEES
WHERE EMP_ID = P_EMP_ID;
DBMS_OUTPUT.PUT_LINE('调试日志:查询到的薪资 = ' || V_SALARY || ',部门ID = ' || V_DEPT_ID);
-- 第二步:按部门计算年终奖,加分支判断
IF V_DEPT_ID = 10 THEN -- 假设10对应市场部
O_BONUS := V_SALARY * 1.5;
ELSIF V_DEPT_ID = 20 THEN -- 假设20对应技术部
O_BONUS := V_SALARY * 2;
ELSE
O_BONUS := V_SALARY * 1;
END IF;
DBMS_OUTPUT.PUT_LINE('调试日志:最终计算的年终奖 = ' || O_BONUS);
-- 异常捕获,打印错误信息
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('调试日志:未找到ID为' || P_EMP_ID || '的员工记录');
O_BONUS := -1; -- 用-1标记异常
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('调试日志:其他错误,代码=' || SQLCODE || ',信息=' || SQLERRM);
O_BONUS := -2;
END CALC_BONUS;
这个示例里,每一步都加了打印:入参对不对、数据库读到的值对不对、分支走的是不是预期的、异常有没有触发。跑的时候只要看这些日志,就能很快发现是把市场部的ID写成11了,还是员工记录被删了,适合新手快速排查小问题,不用额外工具,只要用达梦客户端打开输出窗口就能看结果。
1.2 用达梦自带调试工具逐行排查复杂逻辑
如果存储过程逻辑复杂(比如嵌套循环、多个分支),加太多打印日志会显得杂乱,反复改代码编译也麻烦,这时候可以用达梦自带的调试工具,像拆盲盒一样逐行跟踪。操作步骤也很简单:打开达梦客户端,连接对应数据库,找到要调试的存储过程,右键选「调试」,在想停的行左边点一下加断点,点「运行」后代码会停在断点处,按F8就能单步执行,随时看变量值的变化,就像玩游戏时看每一步操作的结果一样。 这个工具适合逻辑复杂的场景,比如有多层循环的计算、多条件分支的判断,能快速定位到是哪个分支或者循环出了问题。不过它也有小缺点:需要客户端和数据库版本一致,还要开启调试权限,有时候环境配置不对会用不了,生产环境一般不轻易开启,怕影响性能。
二、生产环境存储过程问题的排查思路
2.1 先找“案发场景”再动手
生产环境出问题时,千万不能上来就改代码,要像警察办案一样先找「案发时间、地点、涉案人员」。比如用户反馈“今天下午3点给市场部员工算年终奖,结果错了5个”,那首先确定时间是今天下午3点,操作对象是市场部,然后用达梦的系统视图找对应的执行记录。
-- 技术栈:达梦SQL
-- 查询最近1天内执行过CALC_BONUS存储过程的会话信息
SELECT S.SESS_ID, S.USER_NAME, S.STATE, S.LAST_SQL, S.LAST_EXEC_TIME
FROM V$SESSION S
JOIN V$SQLTEXT T ON S.LAST_SQL_ID = T.SQL_ID
WHERE T.SQL_TEXT LIKE '%CALC_BONUS%'
AND S.LAST_EXEC_TIME >= SYSDATE - 1;
这个SQL就像数据库的监控小黑板,能告诉你哪个用户、哪个时间执行了这个存储过程,会话状态是「正常」还是「出错」,如果状态是「KILLED」或「ERROR」,说明这次执行确实出了问题,接下来就可以针对性排查。
2.2 查后台日志找错误根源
找到有问题的会话后,要查达梦的后台日志,比如安装目录里log文件夹下的ALERT日志,这里面会记录所有数据库的错误信息,比如执行存储过程时的错误代码、具体原因。比如看到错误代码-100,对应信息是「EMPLOYEES表无对应记录」,那问题大概率是这个员工的记录被删了,或者传参时写错了员工ID。 排查时要注意,生产环境的日志不能随便删,要找和问题时间对应的那几条,不要漏看;另外不要仅凭日志就下结论,要结合系统视图的信息交叉验证,避免误判。
三、调试与排查的关键辅助内容
3.1 主要应用场景
这些技巧适合三类场景:第一,开发阶段测存储过程功能,比如刚写完CALC_BONUS,用打印日志或调试工具测计算是否正确;第二,上线前的回归测试,改了存储过程逻辑后,再调试一遍确保不影响其他功能;第三,生产问题的初始排查,用户反馈问题后,先查日志和系统视图,快速缩小范围。
3.2 调试技巧的优缺点
打印埋点的优点:不用额外工具,上手快,适合新手随时用,改完就能看结果;缺点是要改代码,生产环境改的话要注意权限,不能影响其他用户,打太多日志还会占数据库内存,降低性能。调试工具的优点:可视化,不用改代码,能逐行跟踪,适合复杂逻辑,不用反复编译;缺点是环境配置麻烦,客户端版本要匹配,权限要求高,生产环境很少开启。
3.3 调试与排查的注意事项
有几点要特别注意:第一,调试时不要打印敏感信息,比如员工薪资、身份证号,生产环境绝对不能随便打,避免泄露隐私;第二,生产环境排查时,改代码前一定要备份原来的存储过程,不然改坏了会影响更多用户;第三,达梦的系统视图在不同版本里名字可能不一样,比如旧版本里V$SESSION可能叫V$SESS,查之前要对应数据库版本;第四,调试时参数类型要和存储过程一致,比如要NUMBER类型的参数,传字符串就会报错,这个细节很容易被忽略。
3.4 总结
不管是开发调试还是生产排查,核心思路都是「先复现,再定位,最后解决」。开发阶段用打印日志或调试工具,快速找到逻辑问题;生产环境出问题时,先定位场景,再查系统视图和后台日志,找到错误根源再动手。多利用达梦自带的工具,不用自己瞎猜,就能少走很多弯路,提高开发和排查的效率。
评论
围绕“达梦数据库存储过程开发中的调试技巧及生产环境问题排查思路”参与讨论