2

我的数据库中有一个存储过程,看起来像这样

ALTER PROCEDURE [dbo].[GetCountingAnalysisResults] 
    @RespondentFilters varchar
AS
BEGIN

@RespondentFilters = '''8ec94bed-fed6-4627-8d45-21619331d82a, 114c61f2-8935-4755-b4e9-4a598a51cc7f'''

DECLARE @SQL nvarchar(600)

SET @SQL = 
   'SELECT *
    FROM Answer
    WHERE Answer.RespondentId IN ('+@RespondentFilters+'''))
    GROUP BY ChosenOptionId'

exec sp_executesql @SQL

END

它编译并执行,但不知怎的,它并没有给我很好的结果,就像 IN 语句不起作用一样。请,如果有人知道这个问题的解决方案,请帮助我。

4

5 回答 5

3

您绝对应该考虑将 GUID 列表拆分为一个表并加入该表。您应该能够在线找到大量用于将输入字符串拆分为表的表值函数的示例。

否则,您的存储过程很容易受到 SQL 注入的攻击。考虑@RespondentFilters 的以下值:

@RespondentFilters = '''''); SELECT * FROM User; /*'

您的查询将更安全地解析(即验证)参数值并加入:

SELECT *
FROM Answer
WHERE Answer.RespondentId IN (SELECT [Item] FROM dbo.ParseList(@RespondentFilters))
GROUP BY ChosenOptionId

或者

SELECT *
FROM Answer
INNER JOIN dbo.ParseList(@RespondentFilters) Filter ON Filter.Item = Answer.RespondentId
GROUP BY ChosenOptionId

它的效率也稍高一些,因为您不处理动态 SQL(sp_executesql 将缓存查询计划,但我不确定它是否会准确地将您的查询识别为参数化查询,因为它在IN 子句)。

于 2008-09-18T15:59:11.663 回答
2

You need single quotes around each GUID in the list

@RespondentFilters = '''8ec94bed-fed6-4627-8d45-21619331d82a'', ''114c61f2-8935-4755-b4e9-4a598a51cc7f'''
于 2008-09-18T15:45:07.097 回答
1

It looks like you don't have closing quotes around your @RespondentFilters

'8ec94bed-fed6-4627-8d45-21619331d82a, 114c61f2-8935-4755-b4e9-4a598a51cc7f'

Since GUIDs do a string compare, that's not going to work.

Your best bet is to use some code to split the list out into multiple values.

Something like this:


-- This would be the input parameter of the stored procedure, if you want to do it that way, or a UDF
declare @string varchar(500)
set @string = 'ABC,DEF,GHIJK,LMNOPQRS,T,UV,WXY,Z'


declare @pos int
declare @piece varchar(500)

-- Need to tack a delimiter onto the end of the input string if one doesn't exist
if right(rtrim(@string),1)  ','
 set @string = @string  + ','

set @pos =  patindex('%,%' , @string)
while @pos  0
begin
 set @piece = left(@string, @pos - 1)

 -- You have a piece of data, so insert it, print it, do whatever you want to with it.
 print cast(@piece as varchar(500))

 set @string = stuff(@string, 1, @pos, '')
 set @pos =  patindex('%,%' , @string)
end

Code stolen from Raymond Lewallen

于 2008-09-18T15:41:02.737 回答
1

I think you need quotes inside the string too. Try:

@RespondentFilters = '''8ec94bed-fed6-4627-8d45-21619331d82a'',''114c61f2-8935-4755-b4e9-4a598a51cc7f'''

You could also consider parsing the @RespondentFilters into a temporary table.

于 2008-09-18T15:44:26.177 回答
0

为您的答案加油。他们都帮了大忙。我已经通过编写一个拆分函数来解决这个问题,它工作正常。这比我本可以做的有点开销,但你知道,截止日期就在拐角处:)

于 2008-09-20T12:37:09.160 回答