1. 程式人生 > >sql中的if else 的一個小陷阱

sql中的if else 的一個小陷阱

今天遇到一個特別奇葩的問題。一個儲存過程“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對於這樣的錯誤編譯根本通不過。

由此可見,基礎的重要性。這麼一個小問題整整折騰了一天。