在 SQL Server 存储过程的 where 中使用参数作为列

Posted

技术标签:

【中文标题】在 SQL Server 存储过程的 where 中使用参数作为列【英文标题】:Use parameter as column in where in SQL Server stored procedure 【发布时间】:2017-11-02 18:31:02 【问题描述】:
BEGIN
    DECLARE @SQLQuery AS NVARCHAR(MAX)

    IF(@Search IS NOT NULL)
    BEGIN
        DECLARE @dyColumn sysname ;

        IF(@Filter = 'IsNew')
        BEGIN
            SET @dyColumn = 'IsNew'
        END
        ELSE IF(@Filter = 'IsOnSale')
        BEGIN
            SET @dyColumn = 'IsOnSale'
        END
        ELSE IF(@Filter = 'IsFeatured')
        BEGIN
            SET @dyColumn = 'IsFeatured'
        END

        SET @SQLQuery = 'SELECT P.*, C.Id AS CategoryId, C.Name AS CategoryName, C.Logo AS CategoryLogo,
                    CO.Id AS CompanyId, CO.Name AS CompanyName, CO.Logo AS CompanyLogo, COUNT(*) OVER() TotalCount
                    FROM Products P
                    JOIN Categories C ON  P.CategoryId = C.Id
                    JOIN Companies CO ON  P.CompanyId = CO.Id 
                    WHERE P.Name LIKE %'+@Search+'% AND '+@dyColumn+' = true
                    ORDER BY P.Name
                    OFFSET '+CAST(@PageSize AS nvarchar(100))+'*('+CAST(@PageNumber AS nvarchar(100)) +'- 1) ROWS
                    FETCH NEXT '+CAST(@PageSize AS nvarchar(100))+'ROWS ONLY OPTION (RECOMPILE);'

        EXECUTE(@SQLQuery)
    END

这是查询及其在运行时给出的错误

“2”附近的语法不正确。 FETCH 语句中选项 NEXT 的使用无效。

这意味着查询出错了

WHERE P.Name LIKE %'+@Search+'%

【问题讨论】:

如果选择@SQLQuery 会得到什么 请忽略+@dyColumn+' = true 这是+@dyColumn+' = 1 “2”附近的语法不正确。 FETCH 语句中选项 NEXT 的使用无效 查询在将参数作为列传递时导致问题 请显示完整的查询,包括光标。 【参考方案1】:

您不需要动态 sql,只需结合 WHERE 表达式中的列测试过滤器值的值:

SELECT
    P.*
    ,C.Id AS CategoryId
    ,C.Name AS CategoryName
    ,C.Logo AS CategoryLogo
    ,CO.Id AS CompanyId
    ,CO.Name AS CompanyName
    ,CO.Logo AS CompanyLogo
    ,COUNT(*) OVER() TotalCount
FROM
    Products P
    JOIN Categories C
    ON  P.CategoryId = C.Id
    JOIN Companies CO
    ON  P.CompanyId = CO.Id 
WHERE
    @Search IS NOT NULL
    AND P.Name LIKE '%' + @Search + '%'
    AND ( 
       (@Filter= 'IsNew' AND IsNew = 1)
       OR (@Filter= 'IsOnSale' AND IsOnSale = 1)
       OR (@Filter= 'IsFeatured' AND IsFeatured = 1)
       OR (@Filter NOT IN ('IsNew','IsOnSale','IsFeatured'))
    )
ORDER BY
    P.Name
OFFSET  (@PageSize)*(@PageNumber)- 1 ROWS
FETCH NEXT (@PageSize) ROWS ONLY OPTION (RECOMPILE);

如果你真的想使用动态 SQL 而不是执行它SELECT @SQLQuery 然后通过复制到另一个查询窗口来查找语法问题。

【讨论】:

以上是关于在 SQL Server 存储过程的 where 中使用参数作为列的主要内容,如果未能解决你的问题,请参考以下文章

sql server创建视图添加where条件,条件包含一个参数

SQL Server存储过程:if variable = X,case where statement

WHERE 子句中的 OR 会降低 sql 查询性能(sql server)

SQL Server:IF .. ELSE 中的 Where 子句

在存储过程 sql server 2005 中使用函数调用?

在SQL Server存储过程中声明变量列表