在动态 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='')
)
我正在尝试在存储过程中使用动态 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='')
)