在动态 SQL 语句中使用带有通配符的问题

Issue with using like with a wildcard in dynamic SQL statement

我正在尝试在存储过程中使用动态 SQL 语句来根据用户的输入过滤查询。我从一个基本参数开始,需要在数据库中找到匹配的名字。

CREATE PROCEDURE dbo.uspFilter
    @FirstName varchar(100) = null,
    @Debug bit = 1
AS

DECLARE @SQL nvarchar(max);
DECLARE @Params nvarchar(max);
DECLARE @Search nvarchar(300);

SELECT @Params = N'@FirstName varchar(300) = null'
SELECT @SQL = N'SELECT * FROM Table WHERE 1=1'

IF @FirstName IS NOT NULL
    SELECT @Search = N'@FirstName' + N'%'''
    SELECT @SQL = @SQL + N' AND Forename LIKE ''' + @Search

IF @Debug = 1
    @PRINT @SQL

EXEC sp_executeSQL @SQL, @Params, @FirstName = @FirstName;
GO

EXEC dbo.uspFilter @FirstName = 'Test', @Debug = 1;
GO

调试语句的输出看起来正确,但没有返回任何结果:

SELECT * FROM Table WHERE 1=1 AND Forename LIKE '@FirstName%'

编辑:这是我正在寻找的精简版 - 我将使用具有不同搜索条件的多个参数。

这就是您需要的方式:

CREATE PROCEDURE dbo.uspFilter
    @Search varchar(300) = null,
    @Debug bit = 1
AS

DECLARE @SQL nvarchar(max);
DECLARE @Params nvarchar(max);

SELECT @Params = N'@FirstName varchar(300)';
SELECT @SQL = N'SELECT * FROM [Table]';

IF @FirstName IS NOT NULL BEGIN
    SET @SQL = @SQL + N' WHERE Forename LIKE @FirstName + ''%'';';
END ELSE BEGIN
    SET @SQL = @SQL + N';';
END

IF @Debug = 1
    PRINT @SQL;

EXEC sp_executeSQL @SQL, @Params, @FirstName = @Search;
GO

EXEC dbo.uspFilter @Search = 'Steve', @Debug = 1;

请注意,尽管 Crowcoder 关于 SQL 注入的评论很重要,但您可以编写不允许注入的动态 SQL。如上。

编辑:一些细微的更正。

您也可以在不进行动态查询的情况下应用如下动态where条件,请看下面的示例。您可以通过在下面的示例中应用 AND where 子句来加入其他过滤器。

Declare @firstName VARCHAR(50)='sa'

SELECT
    *
FROM Table 
WHERE 
(
    (Forename LIKE '%'+@firstName+'%' AND @firstName!='') 
    OR 
    (@firstName='')
)