簡體   English   中英

重寫動態SQL存儲過程

[英]Rewriting Dynamic SQL Stored Procedure

我正在嘗試重寫動態SQL存儲過程,以避免將SQL語句視為字符串

原始存儲過程

select @sql = 'select AM.AUTHNO, '
        select @sql = @sql + 'AST.DESCR, '
        select @sql = @sql + 'AM.MEMBID_DISP as ''MEMBID'', '
        select @sql = @sql + 'convert(varchar(25),isnull(AM.MEMBNAME,'''')) as member_name, '
        select @sql = @sql + 'isnull(MM.SEX,'''') as member_sex, '
        select @sql = @sql + 'isnull(MM.BIRTH,'''') as member_birth, '
        select @sql = @sql + 'convert(varchar(25),isnull(HC.HPNAME,'''')) as member_healthplan, '
        select @sql = @sql + 'convert(varchar(25),isnull(PM.lastname,'''') + isnull('', '' + PM.firstname,'''')) as provider_name, '
        select @sql = @sql + 'PM.PROVID_DISP as ''PROVID'', '
        select @sql = @sql + '''1'' as ''SORT_ORDER'', AM.MEMBID as ''MEMB_KEYID'', AM.AUTHPCP as ''PROV_KEYID'' '
        select @sql = @sql + ', AM.DBKEY as ''DBKEY'' '
        select @sql = @sql + ', (select DESCR from DB where [KEY] = AM.DBKEY) as ''IPA'' '
        select @sql = @sql + ', AM.AUTHDATE, AM.REQDATE '
        select @sql = @sql + 'from Z_AUTH_MASTERS AM, Z_AUTH_STATUS AST, Z_PROV_MASTERS PM, Z_MEMB_MASTERS MM, Z_HP_CONTRACTS HC '
        select @sql = @sql + 'where AM.DBKEY in (' + DBO.C_SP_AUTH_SEARCH_DBKEY(@DB_KEY,@GUID) + ') '  -- **** CUSTOM
        select @sql = @sql + 'and AM.DBKEY = PM.DBKEY ' 
        select @sql = @sql + 'and AM.AUTHPCP = PM.PROVID '
        select @sql = @sql + 'and AM.DBKEY = AST.DBKEY ' 
        select @sql = @sql + 'and AM.STATUS = AST.CODE '
        select @sql = @sql + 'and AM.DBKEY = MM.DBKEY ' 
        select @sql = @sql + 'and AM.MEMBID = MM.MEMBID '
        select @sql = @sql + 'and AM.DBKEY = HC.DBKEY ' 
        select @sql = @sql + 'and AM.HPCODE = HC.HPCODE '
        if @REFPROV <> '%'
            select @sql = @sql + 'and AM.AUTHPCP_DISP = ''' + @REFPROV + ''' '
        if @AUTHNO <> '%'
            select @sql = @sql + 'and AM.AUTHNO like ''' + @AUTHNO + ''' '
        if @STATUS <> '%'
            select @sql = @sql + 'and AM.STATUS = ''' + @STATUS + ''' '
        if @REQPROV_FIRST <> '%'
            select @sql = @sql + 'and PM.FIRSTNAME like ''' + @REQPROV_FIRST + ''' '
        if @REQPROV_LAST <> '%'
            select @sql = @sql + 'and PM.LASTNAME like ''' + @REQPROV_LAST + ''' '
        if @MEMB_FIRST <> '%'
            select @sql = @sql + 'and MM.FIRSTNM like ''' + @MEMB_FIRST + ''' '
        if @MEMB_LAST <> '%'
            select @sql = @sql + 'and MM.LASTNM like ''' + @MEMB_LAST + ''' '
        if @MEMB_ID <> '%'
            select @sql = @sql + 'and AM.MEMBID_DISP like ''' + @MEMB_ID + ''' '
        if @REQDATE_OP = 'E'
            select @sql = @sql + 'and AM.REQDATE = ''' + @REQDATE_BEGIN + ''' '
        if @REQDATE_OP = 'B'
            select @sql = @sql + 'and (AM.REQDATE >= ''' + @REQDATE_BEGIN + ''' and AM.REQDATE <= ''' + @REQDATE_END + ''') '
        if @AUTDATE_OP = 'E'
            select @sql = @sql + 'and AM.AUTHDATE = ''' + @AUTDATE_BEGIN + ''' '
        if @AUTDATE_OP = 'B'
            select @sql = @sql + 'and (AM.AUTHDATE >= ''' + @AUTDATE_BEGIN + ''' and AM.AUTHDATE <= ''' + @AUTDATE_END + ''') '
        if @EXPDATE_OP = 'E'
            select @sql = @sql + 'and AM.EXPRDATE = ''' + @EXPDATE_BEGIN + ''' '
        if @EXPDATE_OP = 'B'
            select @sql = @sql + 'and (AM.EXPRDATE >= ''' + @EXPDATE_BEGIN + ''' and AM.EXPRDATE <= ''' + @EXPDATE_END + ''') '
        if @FILTER <> '%'
            select @sql = @sql + 'and ' + @FILTER + ' '

        -- only show auths where the Authpcp or reqprov are providers that are linked to this user
        if @IS_SUPER=0
            begin
            select @sql = @sql + 'and ((AM.AUTHPCP in (SELECT PROVID from USER_PROVIDERS where USER_ID = ' + convert(varchar(10),@USER_ID) + ' and DBKEY in (' + DBO.C_SP_AUTH_SEARCH_DBKEY(@DB_KEY,@GUID) + '))) '
            select @sql = @sql + 'or (AM.REQPROV in (SELECT PROVID from USER_PROVIDERS where USER_ID = ' + convert(varchar(10),@USER_ID) + ' and DBKEY in (' + DBO.C_SP_AUTH_SEARCH_DBKEY(@DB_KEY,@GUID) + ')))) '
            end


        -- add sort code here
        select @sql = @sql + 'order by SORT_ORDER asc, '
        if @SORT_COLUMN = 1
            select @sql = @sql + 'AM.AUTHNO desc, '
        if @SORT_COLUMN = 2
            select @sql = @sql + 'AM.STATUS asc, '
        if @SORT_COLUMN = 3
            select @sql = @sql + 'AM.MEMBID_DISP asc, '
        if @SORT_COLUMN = 4
            select @sql = @sql + 'MM.LASTNM asc, '
        if @SORT_COLUMN = 5
            select @sql = @sql + 'MM.SEX asc, '
        if @SORT_COLUMN = 6
            select @sql = @sql + 'MM.BIRTH asc, '
        if @SORT_COLUMN = 7
            select @sql = @sql + 'HC.HPNAME asc, '
        if @SORT_COLUMN = 8
            select @sql = @sql + 'PM.LASTNAME asc, '
        if @SORT_COLUMN = 9
            select @sql = @sql + '''IPA'' asc, '

        -- trim off last ', '
        select @sql = left(@SQL,len(@SQL)-1)
        exec sp_executesql @sql

這就是我到目前為止

        SELECT
            AM.AUTHNO as Auth_No,
            AST.DESCR as Descr,
            AM.MEMBID_DISP as Memb_Id,
            CONVERT(varchar(25), ISNULL(AM.MEMBNAME,'')) as Member_Name,
            ISNULL(MM.SEX,'') as Member_Sex,
            ISNULL(MM.BIRTH,'') as Member_Dob,
            CONVERT(varchar(25), ISNULL(HC.HPNAME,'')) as Member_Hp,
            CONVERT(varchar(25), ISNULL(PM.LASTNAME,'') + ISNULL(', ' + PM.FIRSTNAME, '')) as Provider_Name,
            PM.PROVID_DISP as Prov_Id,
            '1' as SORT_ORDER,
            AM.DBKEY as Db_Key,
            (SELECT DESCR FROM DB WHERE [KEY] = AM.DBKEY) as Ipa,
            AM.AUTHDATE,
            AM.REQDATE              
        FROM
            Z_AUTH_MASTERS AM,
            Z_AUTH_STATUS AST,
            Z_PROV_MASTERS PM, 
            Z_MEMB_MASTERS MM, 
            Z_HP_CONTRACTS HC
        WHERE
            AM.DBKEY IN ( DBO.C_SP_AUTH_SEARCH_DBKEY(@DB_KEY, @GUID))
            AND AM.DBKEY = PM.DBKEY
            AND AM.AUTHPCP = PM.PROVID
            AND AM.DBKEY = AST.DBKEY
            AND AM.STATUS = AST.CODE
            AND AM.DBKEY = MM.DBKEY
            AND AM.MEMBID = MM.MEMBID
            AND AM.DBKEY = HC.DBKEY
            AND AM.HPCODE = HC.HPCODE
            AND (@STATUS IS NULL OR (AM.STATUS = @STATUS))
            AND (@REFPROV IS NULL OR (AM.AUTHPCP_DISP = @REFPROV))
            AND (@AUTHNO IS NULL OR (AM.AUTHNO like @AUTHNO))
            AND (@REQPROV_FIRST IS NULL OR (PM.FIRSTNAME like @REQPROV_FIRST))
            AND (@REQPROV_LAST IS NULL OR (PM.LASTNAME like @REQPROV_LAST))
            AND (@MEMB_FIRST IS NULL OR (MM.FIRSTNM like @MEMB_FIRST))
            AND (@MEMB_LAST IS NULL OR (MM.LASTNM like @MEMB_LAST))
            AND (@MEMB_ID IS NULL OR (AM.MEMBID_DISP like @MEMB_ID))

我很難覆蓋下面的代碼片段

        if @REQDATE_OP = 'E'
            select @sql = @sql + 'and AM.REQDATE = ''' + @REQDATE_BEGIN + ''' '
        if @REQDATE_OP = 'B'
            select @sql = @sql + 'and (AM.REQDATE >= ''' + @REQDATE_BEGIN + ''' and AM.REQDATE <= ''' + @REQDATE_END + ''') '
        if @AUTDATE_OP = 'E'
            select @sql = @sql + 'and AM.AUTHDATE = ''' + @AUTDATE_BEGIN + ''' '
        if @AUTDATE_OP = 'B'
            select @sql = @sql + 'and (AM.AUTHDATE >= ''' + @AUTDATE_BEGIN + ''' and AM.AUTHDATE <= ''' + @AUTDATE_END + ''') '
        if @EXPDATE_OP = 'E'
            select @sql = @sql + 'and AM.EXPRDATE = ''' + @EXPDATE_BEGIN + ''' '
        if @EXPDATE_OP = 'B'
            select @sql = @sql + 'and (AM.EXPRDATE >= ''' + @EXPDATE_BEGIN + ''' and AM.EXPRDATE <= ''' + @EXPDATE_END + ''') '
        if @FILTER <> '%'
            select @sql = @sql + 'and ' + @FILTER + ' '

我嘗試實現CASE語句,但是語法不正確

 WHERE
    CASE
        WHEN @REQDATE_OP = 'E' THEN AM.REQDATE = @REQDATE_BEGIN
        WHEN @REQDATE_OP = 'B' THEN (AM.REQDATE >= @REQDATE_BEGIN AND AM.REQDATE <= @REQDATE_END)
        ....
        ....

    AM.DBKEY IN ( DBO.C_SP_AUTH_SEARCH_DBKEY(@DB_KEY, @GUID))
    AND AM.DBKEY = PM.DBKEY
    AND AM.AUTHPCP = PM.PROVID

CASE陳述式是正確的方法嗎? 如果是這樣,應該如何重寫CASE語句? 還有其他替代方法嗎?

您可以改進此代碼的構造,但是在@FILTER條件下,不重新定義整個過程就不太可能擺脫動態代碼。 這是單個SELECT中的整個塊:

select @sql = 'select AM.AUTHNO, 
    AST.DESCR, 
    AM.MEMBID_DISP as ''MEMBID'', 
    convert(varchar(25),isnull(AM.MEMBNAME,'''')) as member_name, 
    isnull(MM.SEX,'''') as member_sex, 
    isnull(MM.BIRTH,'''') as member_birth, 
    convert(varchar(25),isnull(HC.HPNAME,'''')) as member_healthplan, 
    convert(varchar(25),isnull(PM.lastname,'''') + isnull('', '' + PM.firstname,'''')) as provider_name, 
    PM.PROVID_DISP as ''PROVID'', 
    ''1'' as ''SORT_ORDER'', AM.MEMBID as ''MEMB_KEYID'', AM.AUTHPCP as ''PROV_KEYID'' 
    , AM.DBKEY as ''DBKEY'' 
    , (select DESCR from DB where [KEY] = AM.DBKEY) as ''IPA'' 
    , AM.AUTHDATE, AM.REQDATE 
    from Z_AUTH_MASTERS AM
    INNER JOIN Z_AUTH_STATUS AST
        ON AM.DBKEY = AST.DBKEY  
        and AM.STATUS = AST.CODE 
    INNER JOIN Z_PROV_MASTERS PM
        ON AM.DBKEY = PM.DBKEY  
        and AM.AUTHPCP = PM.PROVID 
    INNER JOIN Z_MEMB_MASTERS MM
        ON AM.DBKEY = MM.DBKEY  
        and AM.MEMBID = MM.MEMBID 
    INNER JOIN Z_HP_CONTRACTS HC 
        ON AM.DBKEY = HC.DBKEY  
        and AM.HPCODE = HC.HPCODE   
    where AM.DBKEY in (' + DBO.C_SP_AUTH_SEARCH_DBKEY(@DB_KEY,@GUID) + ') ' +   -- **** CUSTOM
    CASE
        WHEN @REFPROV <> '%'
            THEN 'and AM.AUTHPCP_DISP = ''' + @REFPROV + ''' ' 
        ELSE ''
    END + CASE
        WHEN @AUTHNO <> '%'
            THEN 'and AM.AUTHNO like ''' + @AUTHNO + ''' '
        ELSE ''
    END + CASE
        WHEN @STATUS <> '%'
            THEN 'and AM.STATUS = ''' + @STATUS + ''' '
        ELSE ''
    END + CASE
        WHEN @REQPROV_FIRST <> '%'
            THEN 'and PM.FIRSTNAME like ''' + @REQPROV_FIRST + ''' '
        ELSE ''
    END + CASE
        WHEN @REQPROV_LAST <> '%'
            THEN 'and PM.LASTNAME like ''' + @REQPROV_LAST + ''' '
        ELSE ''
    END + CASE
        WHEN @MEMB_FIRST <> '%'
            THEN 'and MM.FIRSTNM like ''' + @MEMB_FIRST + ''' '
        ELSE ''
    END + CASE
        WHEN @MEMB_LAST <> '%'
            THEN 'and MM.LASTNM like ''' + @MEMB_LAST + ''' '
        ELSE ''
    END + CASE
        WHEN @MEMB_ID <> '%'
            THEN 'and AM.MEMBID_DISP like ''' + @MEMB_ID + ''' '
        ELSE ''
    END + CASE @REQDATE_OP
        WHEN 'E'
            THEN 'and AM.REQDATE = ''' + @REQDATE_BEGIN + ''' '
        WHEN 'B'
            THEN 'and (AM.REQDATE >= ''' + @REQDATE_BEGIN + ''' and AM.REQDATE <= ''' + @REQDATE_END + ''') '
    END + CASE @AUTDATE_OP 
        WHEN 'E'
            THEN 'and AM.AUTHDATE = ''' + @AUTDATE_BEGIN + ''' '
        WHEN 'B'
            THEN 'and (AM.AUTHDATE >= ''' + @AUTDATE_BEGIN + ''' and AM.AUTHDATE <= ''' + @AUTDATE_END + ''') '
    END + CASE @EXPDATE_OP 
        WHEN 'E'
            THEN 'and AM.EXPRDATE = ''' + @EXPDATE_BEGIN + ''' '
        WHEN 'B'
            THEN 'and (AM.EXPRDATE >= ''' + @EXPDATE_BEGIN + ''' and AM.EXPRDATE <= ''' + @EXPDATE_END + ''') '
    END + CASE
        WHEN @FILTER <> '%'
            THEN 'and ' + @FILTER + ' '
        ELSE ''
    END + CASE        -- only show auths where the Authpcp or reqprov are providers that are linked to this user
        WHEN @IS_SUPER=0
            THEN 'and ((AM.AUTHPCP in (SELECT PROVID from USER_PROVIDERS where USER_ID = ' + convert(varchar(10),@USER_ID) + ' and DBKEY in (' + DBO.C_SP_AUTH_SEARCH_DBKEY(@DB_KEY,@GUID) + '))) 
        or (AM.REQPROV in (SELECT PROVID from USER_PROVIDERS where USER_ID = ' + convert(varchar(10),@USER_ID) + ' and DBKEY in (' + DBO.C_SP_AUTH_SEARCH_DBKEY(@DB_KEY,@GUID) + ')))) '
    END + 'order by SORT_ORDER asc' +
    CASE @SORT_COLUMN 
        WHEN 1
            THEN ', AM.AUTHNO desc'
        WHEN 2
            THEN ', AM.STATUS asc'
        WHEN 3
            THEN ', AM.MEMBID_DISP asc'
        WHEN 4
            THEN ', MM.LASTNM asc'
        WHEN 5
            THEN ', MM.SEX asc'
        WHEN 6
            THEN ', MM.BIRTH asc'
        WHEN 7
            THEN ', HC.HPNAME asc'
        WHEN 8
            THEN ', PM.LASTNAME asc'
        WHEN 9
            THEN ', ''IPA'' asc'
    END

exec sp_executesql @sql

另外,請注意:為什么對常數進行排序? (WHEN 9條件)。 只需刪除它,因為它根本不會改變排序的順序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM