SQL Server:如何在存储过程中设置动态列名

时间:2014-06-25 18:23:29

标签: sql sql-server stored-procedures dynamic

我对动态程序很陌生,希望有人能帮助我解决以下问题。

似乎我的问题是我的Where子句的AND部分。我在这里没有收到错误 - 它只是没有返回任何结果。

编辑:我的动态列名称为“R. @ searchCategory”。

到目前为止我的程序:

ALTER PROCEDURE [dbo].[FetchRequests]
    @searchCategory nvarchar(100) = '',
    @searchTerm nvarchar(256) = ''
AS
BEGIN
    BEGIN   

    DECLARE @sql nvarchar(max)  
    SET @sql = 'SELECT TOP 100
                R.logID,
                R.flag,
                R.reviewer,
                R.modBy,
                A.Email AS requesterEmail,
                B.Email AS approverEmail,
                L.locale AS region,
                L.country AS countryName
    FROM        LogRequests R
    LEFT JOIN   EmpTable A
    ON          A.NTID = R.requester
    LEFT JOIN   EmpTable B
    ON          B.NTID = R.approver
    INNER JOIN   Locales_Countries L
    ON          R.country = L.isoCode
    WHERE       (R.logStatus LIKE ''%Completed%'' OR R.logStatus LIKE ''%Closed%'') 
    AND         R.' + @searchCategory + ''' LIKE ''%' + @searchTerm + '%''
    ORDER BY    R.dateNeeded desc, R.dateRec desc, R.prio desc, R.EID desc
    FOR XML PATH(''requests''), ELEMENTS, TYPE, ROOT(''ranks'')'

    EXEC(@sql)

    END
END

非常感谢,迈克。

2 个答案:

答案 0 :(得分:2)

您的AND语句中有太多引号......

制作本:

AND         R.' + @searchCategory + ''' LIKE ''%' + @searchTerm + '%''

像这样:

AND         R.' + @searchCategory + ' LIKE ''%' + @searchTerm + '%''

结果:

DECLARE @sql nvarchar(max), @searchCategory nvarchar(max), @searchTerm nvarchar(max)

set @searchCategory = 'something'
set @searchTerm = 'to look for'

    SET @sql = 'SELECT TOP 100
                R.logID,
                R.flag,
                R.reviewer,
                R.modBy,
                A.Email AS requesterEmail,
                B.Email AS approverEmail,
                L.locale AS region,
                L.country AS countryName
    FROM        LogRequests R
    LEFT JOIN   EmpTable A
    ON          A.NTID = R.requester
    LEFT JOIN   EmpTable B
    ON          B.NTID = R.approver
    INNER JOIN   Locales_Countries L
    ON          R.country = L.isoCode
    WHERE       (R.logStatus LIKE ''%Completed%'' OR R.logStatus LIKE ''%Closed%'') 
    AND         R.' + @searchCategory + ' LIKE ''%' + @searchTerm + '%''
    ORDER BY    R.dateNeeded desc, R.dateRec desc, R.prio desc, R.EID desc
    FOR XML PATH(''requests''), ELEMENTS, TYPE, ROOT(''ranks'')'

    print @sql

我总是打印我的动态sql ...并将输出复制到一个新窗口,看看是否有任何转义不应该是。

注意:请研究SQL注入攻击,并使用sp_executeSQL - EXEC是不好的做法。

答案 1 :(得分:1)

到我发布时,还有另一个正确答案:你在@sql定义中添加了太多单引号。

捕获这些简单错误的一种方法是添加print @sql,以便在尝试执行查询之前查看查询的读取方式。我把它包含在下面的修改过的脚本中:

ALTER PROCEDURE [dbo].[FetchRequests]
    @searchCategory nvarchar(100) = '',
    @searchTerm nvarchar(256) = ''
AS
BEGIN
    BEGIN   

    DECLARE @sql nvarchar(max)  
    SET @sql = 'SELECT TOP 100
                R.logID,
                R.flag,
                R.reviewer,
                R.modBy,
                A.Email AS requesterEmail,
                B.Email AS approverEmail,
                L.locale AS region,
                L.country AS countryName
    FROM        LogRequests R
    LEFT JOIN   EmpTable A
    ON          A.NTID = R.requester
    LEFT JOIN   EmpTable B
    ON          B.NTID = R.approver
    INNER JOIN   Locales_Countries L
    ON          R.country = L.isoCode
    WHERE       (R.logStatus LIKE ''%Completed%'' OR R.logStatus LIKE ''%Closed%'') 
    AND         R.' + @searchCategory + ' LIKE ''%'' + @searchTerm + ''%''
    ORDER BY    R.dateNeeded desc, R.dateRec desc, R.prio desc, R.EID desc
    FOR XML PATH(''requests''), ELEMENTS, TYPE, ROOT(''ranks'')'

    --print @sql
    EXEC(@sql)

    END
END