[T-SQL] 用CASE WHEN 切换查询条件

今天检查同事代码,看到一个Procedure有点冗余.

改之前:

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

BEGIN

       IF 'Y'=(select
            (case when decl_submit_time is null then 'Y'
             else 'N'
             end) IS_NULL_SUBMIT_TIME
            from T_BC_DEC_DECLARATION 
            where dec_id=@p_dec_id)
     BEGIN
     SELECT 
   .........
    FROM T_BC_DEC_GOODS t, T_BC_DEC_DECLARATION P,T_BC_TCS_TARIFF R
    WHERE t.DEC_ID=P.DEC_ID
    AND P.DEC_ID=@p_dec_id
    AND t.HS_CODE=R.TARIFF_CODE
    AND R.TARIFF_EFF_DATE<=(CONVERT(VARCHAR(10), GETDATE(), 101))
 AND R.TARIFF_EXP_DATE>=(CONVERT(VARCHAR(10), GETDATE(), 101))
    AND
   (
            P.APP_ST = @p_draft_dec_st             -- Draft status.
     AND P.CREATED_BY = @p_created_by            -- Current user.
     OR
             (P.APP_ST IS NULL OR P.APP_ST <> @p_draft_dec_st )
     AND
     (
            P.AGENT_REG_NO = @p_agent_reg_no       -- Current agent.
            OR @p_is_rced_user = 'Y'
      ) 
     )
   END
  else
   begin
      SELECT 
    .........
    FROM T_BC_DEC_GOODS t, T_BC_DEC_DECLARATION P,T_BC_TCS_TARIFF R
    WHERE t.DEC_ID=P.DEC_ID
    AND P.DEC_ID=@p_dec_id
    AND t.HS_CODE=R.TARIFF_CODE
    AND R.TARIFF_EFF_DATE<=(CONVERT(VARCHAR(10),P.DECL_SUBMIT_TIME, 101))
 AND R.TARIFF_EXP_DATE>=(CONVERT(VARCHAR(10),P.DECL_SUBMIT_TIME, 101))
    AND
   (
            P.APP_ST = @p_draft_dec_st             -- Draft status.
     AND P.CREATED_BY = @p_created_by            -- Current user.
     OR
             (P.APP_ST IS NULL OR P.APP_ST <> @p_draft_dec_st )
     AND
     (
            P.AGENT_REG_NO = @p_agent_reg_no       -- Current agent.
            OR @p_is_rced_user = 'Y'
      ) 
     )
   END

需求:
 如果T_BC_DEC_DECLARATION P中的DEC_SUBMIT_TIME为空,那么就用系统日期来比较;如果存在值,就用提交时间比较. 实际情景, 如果报关时,在提交请求后,提交请求的时间就是一个标准,比如汇率,代码值都以提交时间为准;但是你如果只是提交草稿,那么,以最新的日期时间来取最新的汇率等相关时效数据.
所以,同事就用这个语句来切换查询,
 IF 'Y'=(select
            (case when decl_submit_time is null then 'Y'
             else 'N'
             end) IS_NULL_SUBMIT_TIME
            from T_BC_DEC_DECLARATION 
            where dec_id=@p_dec_id)

 缺点:
代码冗余,将来如果需求改变,需要改两处代码

解决:
定义临时变量,同时直接在Convert中用CASE WHEN 切换查询条件.

代码为:

DECLARE @REFFLAG VARCHAR

SET @REFFLAG = (select
            (case when decl_submit_time is null then 'Y'
             else 'N'
             end) IS_NULL_SUBMIT_TIME
            from T_BC_DEC_DECLARATION 
            where dec_id=@p_dec_id)

     SELECT 
     .......
    FROM T_BC_DEC_GOODS t, T_BC_DEC_DECLARATION P,T_BC_TCS_TARIFF R
    WHERE t.DEC_ID=P.DEC_ID
    AND P.DEC_ID=@p_dec_id
    AND t.HS_CODE=R.TARIFF_CODE
    AND
    R.TARIFF_EFF_DATE<=(CONVERT(VARCHAR(10), CASE WHEN @REFFLAG = 'Y' THEN GETDATE() ELSE P.DECL_SUBMIT_TIME END,101))
    AND
    R.TARIFF_EXP_DATE>=(CONVERT(VARCHAR(10),CASE WHEN @REFFLAG = 'Y' THEN GETDATE() ELSE P.DECL_SUBMIT_TIME END,101))

    AND
   (
            P.APP_ST = @p_draft_dec_st             -- Draft status.
     AND P.CREATED_BY = @p_created_by            -- Current user.
     OR
             (P.APP_ST IS NULL OR P.APP_ST <> @p_draft_dec_st )
     AND
     (
            P.AGENT_REG_NO = @p_agent_reg_no       -- Current agent.
            OR @p_is_rced_user = 'Y'
      ) 
     )

不知道这个是不是最佳方案,如果大家有更好的方案,一起探讨.

 

posted on 2008-04-07 21:43  楚天碧海  阅读(3342)  评论(0)    收藏  举报

导航