You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用DECLARE变量作为表列名在WHERE子句中使用?最佳实践

Dynamic Column Filtering in SQL Server: Avoiding CASE WHEN or Unsafe Dynamic SQL

Got it, let's break down why your current query isn't working first. When you use @ProductLines directly in the WHERE clause like (@ProductLines Like '%' + @searchProductlines + '%'), SQL treats @ProductLines as a literal string (the value 'usr_author') instead of referencing the actual column. So you're comparing the string 'usr_author' to '%hc%'—that's why it never returns the results you want.

Here are the best practices for your scenario, depending on your needs:

1. Parameterized Dynamic SQL (Best for Flexible/Scalable Column Selection)

If you need to support any column from the Products table (or a growing list of columns), this is the way to go. It fixes the literal string issue while keeping your query safe from SQL injection (unlike raw EXEC('code') which can be risky if not handled properly).

The key here is using sp_executesql for parameterization, QUOTENAME() to safely escape column names, and validating that the column exists before executing:

DECLARE @ProductLines nvarchar(50) = 'usr_author'
DECLARE @searchProductlines nvarchar(50) = 'hc'
DECLARE @sql nvarchar(MAX)

-- First, validate the column exists to prevent invalid references and injection
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS 
           WHERE TABLE_NAME = 'Products' AND COLUMN_NAME = @ProductLines)
BEGIN
    -- Build the dynamic SQL with safe column escaping
    SET @sql = N'SELECT TOP 20 
                    Productid as Produktid, 
                    usr_Author AS Author, 
                    Header AS Title, 
                    usr_Publisher AS Publisher, 
                    CustomerId AS Customerid 
                FROM Products 
                WHERE ' + QUOTENAME(@ProductLines) + N' LIKE ''%'' + @search + ''%'''

    -- Execute with parameterized search value to avoid injection and handle data types correctly
    EXEC sp_executesql @sql, N'@search nvarchar(50)', @search = @searchProductlines
END
ELSE
BEGIN
    -- Throw an error if the column doesn't exist
    RAISERROR('Invalid column name specified in @ProductLines', 16, 1)
END

This approach also solves your GETDATE() issue from earlier—if you need to include date logic, you can write it directly in the dynamic SQL string (e.g., WHERE DateColumn >= GETDATE()) instead of trying to concatenate it as a string.

2. CASE WHEN (Best for Fixed, Limited Column Options)

If your dropdown menu only includes a small, fixed set of columns (like usr_author, usr_Publisher, and Header), a concise CASE WHEN avoids dynamic SQL entirely. It's simpler and has no injection risk:

DECLARE @ProductLines nvarchar(50) = 'usr_author'
DECLARE @searchProductlines nvarchar(50) = 'hc'

SELECT TOP 20 
    Productid as Produktid, 
    usr_Author AS Author, 
    Header AS Title, 
    usr_Publisher AS Publisher, 
    CustomerId AS Customerid 
FROM Products 
WHERE 
    CASE @ProductLines
        WHEN 'usr_author' THEN usr_Author
        WHEN 'usr_Publisher' THEN usr_Publisher
        WHEN 'Header' THEN Header
        -- Add more columns here as needed
        ELSE NULL -- Return no matches if invalid column is passed
    END LIKE '%' + @searchProductlines + '%'

3. CHOOSE (Simpler Alternative for Fixed Columns, SQL Server 2012+)

If you're on SQL Server 2012 or later, CHOOSE can make the syntax a bit cleaner for fixed columns. You just map your column names to an index:

DECLARE @ProductLines nvarchar(50) = 'usr_author'
DECLARE @searchProductlines nvarchar(50) = 'hc'

-- Map column name to an index for CHOOSE
DECLARE @colIndex int = CASE @ProductLines
                            WHEN 'usr_author' THEN 1
                            WHEN 'usr_Publisher' THEN 2
                            WHEN 'Header' THEN 3
                        END

SELECT TOP 20 
    Productid as Produktid, 
    usr_Author AS Author, 
    Header AS Title, 
    usr_Publisher AS Publisher, 
    CustomerId AS Customerid 
FROM Products 
WHERE CHOOSE(@colIndex, usr_Author, usr_Publisher, Header) LIKE '%' + @searchProductlines + '%'

Which Should You Pick?

  • Go with parameterized dynamic SQL if you need flexibility (supporting any column or future columns). It's the most scalable and safe when implemented correctly.
  • Use CASE WHEN/CHOOSE if your column options are fixed and limited. It's simpler and avoids the complexity of dynamic SQL.

内容的提问来源于stack exchange,提问作者Mark Mazur Lussenburg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:56:37