与SQL Server中的EXEC sp_executeSQL和Exec不同的结果

时间:2018-09-15 11:27:17

标签: sql-server

我知道上述两种方法有很多示例,但是不幸的是,我没有从任何方法中得到任何积极的结果。请在特定情况下帮助我。

我创建了一个用于过滤数据的用户过滤器应用。用户定义搜索条件后,它将为用户选择的所有过滤器创建列和值的列表,并创建一个配置文件。

需要时,用户只需选择此配置文件并从给定数据中搜索即可。

DECLARE @FilterID INT = 1, @filtertext VARCHAR(MAX)

SELECT
    @filtertext = dbo.GetWhereCriteriaFunction(@FilterID)
    --here @filtertext = 'And Field1 In (ValueList)  And Field2 In (ValueList)  And (Field3 Between 1 And 2 OR Field3 Between 3 And 4) '

DECLARE @Filter NVARCHAR(MAX) = 'SELECT 1 FROM Tablename WHERE ''A''=''A'' + @fText'

-- Method 1
EXEC sp_executeSQL @Filter, N'@fText varchar(max)', @fText = @filtertext

-- Method 2
EXEC ('SELECT 1 FROM TableName WHERE 1=1' + @filtertext)

输出:

  • 方法1:0行
  • 方法2:125行

有人可以在上述情况下指导我,为什么两个结果彼此不同吗?从逻辑上来说,两个结果应该返回相同的输出

3 个答案:

答案 0 :(得分:0)

DECLARE @Filter NVARCHAR(MAX) = 'SELECT 1 FROM Tablename WHERE ''A''=''A'' + @fText'

此行将'A'@fText合并在一起。如WHERE 'A' = ('A' + @fText)

答案 1 :(得分:0)

好吧,您正在动态构建SQL,方法2完全可以实现。 但是,方法1是受限制的版本,您只能传入参数值,而不能传入其他值(没有filedname或任何其他关键字)。 因此,使用像这样的参数表就可以了:

DECLARE @filtertext NVARCHAR(MAX)
SET @filtertext = N' 1 '
DECLARE @Filter NVARCHAR(MAX) = 'SELECT 1 FROM Tablename WHERE 1=1 and Field1 = @fText'
EXEC sp_executeSQL 
    @Filter, 
    N'@fText nvarchar(max)', 
    @fText=@filtertext

因为只传递值。

使用以下参数将无效

DECLARE @filtertext NVARCHAR(MAX)
SET @filtertext = N' AND Field1 = 1 '
DECLARE @Filter NVARCHAR(MAX) = 'SELECT 1 FROM Tablename WHERE 1=1 @fText'
EXEC sp_executeSQL 
    @Filter, 
    N'@fText nvarchar(max)', 
    @fText=@filtertext

因为您不仅传递值-它还包含Field1和AND关键字作为WHERE语句的一部分,而过程sp_executeSQL不允许这样做。

答案 2 :(得分:0)

假设@filtertext的值以空白开头,则第一个WHERE子句的计算结果为

WHERE 'A' = 'A And Field1 In (ValueList)  And Field2 In (ValueList)  And (Field3 Between 1 And 2 OR Field3 Between 3 And 4)'

这显然是错误的(因此查询不返回任何行),并确保它不是您想要的。

sp_executeSQL过程的参数旨在提供查询参数的值。它们无意替换查询字符串的一部分。

因此,第二种方法是您想要的方法。