sql中的if else 的一个小陷阱

来源:互联网 发布:摩托分期付款怎么算法 编辑:程序博客网 时间:2024/06/05 19:54

今天遇到一个特别奇葩的问题。一个存储过程“SP_MODI_TPAYNOTICE_ZHONGTAI”有如下代码。

DECLARE @V_USER_ID INT

.............

IF @V_USER_ID = 5 BEGIN
    --同步修改事物正文
        EXEC @V_RET = SP_INNER_MODI_TPAYNOTICEINFO_USERID5  @IN_PROBLEMID           ////SP_INNER_MODI_TPAYNOTICEINFO_USERID5 是一个存储过程
        IF @V_RET < 0 RAISERROR('Error raise in SP_INNER_MODI_TPAYNOTICEINFO_USERID5',16,99)
      --划款指令、非划款指令设定流程线路
SELECT @V_IS_HKZL = SUBSTRING(FK_TYPE,3,1) FROM TPAYNOTICE WHERE PROBLEMID = @IN_PROBLEMID
       IF @V_IS_HKZL = 1
BEGIN
UPDATE TPROBLEMS SET STATE_TYPE = 205 WHERE PROBLEMID = @IN_PROBLEMID
END
ELSE
BEGIN
UPDATE TPROBLEMS SET STATE_TYPE = 206 WHERE PROBLEMID = @IN_PROBLEMID
END
 END
 EXEC @V_RET = SP_MODI_TCOMMCREDIT_DESCRIPTION @IN_PROBLEMID,@IN_FK_BUSI_ID
    IF @V_RET < 0 RAISERROR('Error raise in SP_INNER_MODI_TPAYNOTICEINFO_USERID5',16,99)


    ELSE
    BEGIN
    --同步修改事物正文
        EXEC @V_RET = SP_INNER_MODI_TPAYNOTICEINFO_USERID7 @IN_PROBLEMID       //SP_INNER_MODI_TPAYNOTICEINFO_USERID7 是一个存储过程
        IF @V_RET < 0 RAISERROR('Error raise in SP_INNER_MODI_TPAYNOTICEINFO_USERID7',16,99)
    END

由上下文,@V_USER_ID 的值确实是5,(我查询了数据库),但事务的结果明显表示这里执行的是“SP_INNER_MODI_TPAYNOTICEINFO_USERID7”这个过程,一开始没注意,就怀疑@V_USER_ID 这个值的获取的时候是不是有什么失误,或者调用的时候是不是根本不是调用的这个过程,所以才会出现这么莫名其妙的结果。尝试过从调用这个存储过程的java代码开始复查,是否有哪些遗漏导致调的是别的存储过程。也尝试过是不是@V_USER_ID 的类型有问题。曾经将@V_USER_ID 的类型改为INTEGER,试过改成

if(ISNULL(@V_USER_ID,0) =5,试过if(ISNULL(@V_USER_ID,0) == 5。均已失败告终。最后经过一层层的定位,问题肯定出在这里,再仔细一看,在if @V_USER_ID = 5 

else begin ... end 中间有一段代码 EXEC @V_RET = SP_MODI_TCOMMCREDIT_DESCRIPTION @IN_PROBLEMID,@IN_FK_BUSI_ID,就是这一段代码将严格if else 语句生生拆成了两个语句,导致后面的SP_INNER_MODI_TPAYNOTICEINFO_USERID7 也被执行,而这个过程跟SP_INNER_MODI_TPAYNOTICEINFO_USERID5 大同小异,而把SP_INNER_MODI_TPAYNOTICEINFO_USERID5 给覆盖掉了。


所以,sql 中if else语句中间不能加多余语句,它会将这个判断结构拆分为两个语句,而且没有语法错误。不像java,java对于这样的错误编译根本通不过。

由此可见,基础的重要性。这么一个小问题整整折腾了一天。


0 0
原创粉丝点击