1

也许我没有正确地做某事,但我需要创建一个字符串列表来过滤一些 SQLSELECT查询,我能找到的只是转义单个参数值的答案。

给定这个数组:

string[] domains = new string[] { "sec", "krn", "op", "ip" };

我需要创建这个查询

SELECT * FROM user_domains WHERE name IN ("sec", "krn", "op", "ip")

注意:这不是一个真正的查询,但说明了这个问题的重点。

一个天真的解决方案是创建一个查询

SELECT * FROM user_domains WHERE name IN (@p1, @p2, @p3, @p4)

并使用格式化为的参数执行查询

Dictionary<string,string> inTerms = domains
     .Select((t, i) => new { Key = "p" + i, Term = t })
     .ToDictionary(item => item.Key, item => item.Term,
                   StringComparer.OrdinalIgnoreCase);

还有另一种方法吗?

更新

使用逗号或以其他方式分隔的术语字符串执行简单的字符串比较(aka )是否同样容易和快速?index of

前任:

SELECT * FROM user_domains WHERE CHARINDEX(name, @terms) > 0

4

1 回答 1

1

我使用一个函数来做到这一点

CREATE FUNCTION dbo.fnListToCol (
    @sInputList VARCHAR(8000) -- List of delimited items
  , @sDelimiter VARCHAR(2) = '|' -- delimiter that separates items
) RETURNS @List TABLE (item VARCHAR(8000))

BEGIN
DECLARE @sItem VARCHAR(8000)
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
 BEGIN
 SELECT
  @sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1))),
  @sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))

 IF LEN(@sItem) > 0
  INSERT INTO @List SELECT @sItem
 END

IF LEN(@sInputList) > 0
 INSERT INTO @List SELECT @sInputList -- Put the last item in
RETURN
END
GO

然后在您的代码中构建一个分隔参数(例如“sec|krn”)并传递给如下过程:

WHERE ( ( VSSAS.Location IN ( SELECT * FROM  dbo.fnListToCol(@LocationFilter, '|') ) ) OR ( @LocationFilter IS NULL ) )
于 2013-03-18T11:19:48.733 回答