[英]Rewriting Dynamic SQL Stored Procedure
I am trying to rewrite a Dynamic SQL Stored Procedure to avoid treating the SQL statement as a string 我正在尝试重写动态SQL存储过程,以避免将SQL语句视为字符串
The original stored procedure 原始存储过程
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
This is what I have so far 这就是我到目前为止
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))
I am having a difficult time coverting the following snippet of code 我很难覆盖下面的代码片段
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 + ' '
I've tried implementing a CASE statement, but the syntax is incorrect 我尝试实现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
Is a CASE statement the correct approach? CASE陈述式是正确的方法吗? If so, how should the CASE statement be re-written? 如果是这样,应该如何重写CASE语句? Are there other alternative approaches? 还有其他替代方法吗?
You can improve the construction of this code, but with the @FILTER condition, it is unlikely that you can rid yourself of dynamic code without redefining the entire process. 您可以改进此代码的构造,但是在@FILTER条件下,不重新定义整个过程就不太可能摆脱动态代码。 Here is the entire block in a single SELECT: 这是单个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
Also, one note: Why is there a sort on a constant? 另外,请注意:为什么对常数进行排序? (the WHEN 9 condition). (WHEN 9条件)。 Just remove that, as it will not change the order of the sort at all. 只需删除它,因为它根本不会改变排序的顺序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.