You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SQL Continue Handler时如何获取真实SQLCODE返回码?

DB2存储过程:捕获每个约束操作的SQLCODE问题解决

问题描述

在Linux环境下开发DB2存储过程,需要对5张表执行7个约束的删除/添加操作,要求每个操作执行完成后返回对应的SQLCODE。但最初的实现中,使用Continue Handler后会导致SQLCODE被清零,比如连续执行两次删除操作时,第二次所有操作的返回码都显示为0,和实际执行结果不符。

初始代码(存在问题)

Case p_Action
When 'DROP' Then
  Begin
    Declare Continue Handler for Not_Found Begin End;

    Set v_MsgText = 'DROP LOC Check Constraint failed.';
    Set v_SqlStmt = 'ALTER TABLE LIBRAT.APNVEND_RECORD_APNV_LOC_DATA DROP CONSTRAINT LIBRAT_APNVEND_RECORD_APNV_LOC_DATA_C1';
    Execute Immediate v_SqlStmt;
    Set v_MsgText = 'DROP LOC Check Constraint rc=' || SQLCODE;
    Call UTL_FILE.PUT_LINE(v_LogHandle, v_MsgText);
...snip...

问题原因

初始代码中的Continue Handler仅做了空处理(Begin End;),当触发Not_Found等异常时,DB2会重置SQLCODE为0以让程序继续执行,导致后续获取到的SQLCODE并非实际操作的返回码。

解决方法及可行代码

通过声明局部变量存储捕获到的错误码,避免直接依赖被重置的SQLCODE,具体实现如下:

Begin
    Declare l_RetCode   Int;
    Declare Continue Handler for Is_Duplicate, Missing_Keys, Missing_Rows
        Begin
            Set l_RetCode = SQLCODE;
        End;

    Set v_MsgText = 'ADD LOC Check Constraint failed.';
    Set v_SqlStmt = 'ALTER TABLE LIBRAT.APNVEND_RECORD_APNV_LOC_DATA ADD CONSTRAINT LIBRAT_APNVEND_RECORD_APNV_LOC_DATA_C1 CHECK ( APNV_LOC > 0 )';
    Execute Immediate v_SqlStmt;
    Set v_MsgText = 'ADD LOC Check Constraint rc=' || Coalesce(l_RetCode,0);
    Call UTL_FILE.PUT_LINE(v_LogHandle, v_MsgText);
    Set l_RetCode = NULL;
...snip...

关键改进点

  • 新增局部变量l_RetCode,专门用于保存Handler捕获到的SQLCODE
  • 在Continue Handler中把触发异常时的SQLCODE赋值给l_RetCode,而非空处理
  • 操作执行完成后,用Coalesce(l_RetCode, 0)获取结果:若有异常则用捕获到的错误码,无异常则返回0
  • 每次操作结束后重置l_RetCode为NULL,确保不会影响下一个操作的结果判断

内容的提问来源于stack exchange,提问作者Dave Clark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 23:16:01