【问题标题】:SQL Server: how to set dynamic column name in stored procedureSQL Server:如何在存储过程中设置动态列名
【发布时间】:2014-08-16 10:34:28
【问题描述】:

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

看来我的问题在于 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

非常感谢,迈克。

【问题讨论】:

  • 我很惊讶这会执行 - 你有一个额外的单引号,就在 @searchCategory 之后应该使语句抛出语法异常。此外,你真的很容易受到 SQL 注入攻击......

标签: sql sql-server stored-procedures dynamic


【解决方案1】:

你的 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 是不好的做法。

【讨论】:

  • 修复了它 - 太棒了!非常感谢 - 没想到会这么容易。 :) 我会尽快接受。
【解决方案2】:

到我发帖的时候,已经有另一个正确答案了:你在@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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    相关资源
    最近更新 更多