如何使用内联SQL参数化IN语句的集合?

时间:2009-12-22 22:30:43

标签: sql ado.net

  

可能重复:
  Parameterizing a SQL IN clause?

嗨,我的查询如下:

SELECT 
    CompanyId 
FROM 
    CompanyTable 
WHERE 
    CompanyName IN ('Subway', 'A & W', 'Pizzahut')

有什么办法可以使用sql参数作为名单?

这不是存储过程(我更喜欢但不能在此项目中使用)。当我说'参数'时,我指的是参数化内联sql中的参数。

我使用MS Enterprise Library,因此我的参数化内联sql看起来像这样:

string sql = "SELECT * FROM Company WHERE CompanyID = @companyId";
Database db = DatabaseFactory.CreateDatabase();
DbCommand dbCommand = db.GetSqlStringCommand(sql);
db.AddInParameter(dbCommand, "companyId", DbType.Int32, 123);
...

对于像上面这样的简单案例,它非常简单。但是当谈到像

这样的东西时
SELECT 
    CompanyId 
FROM 
    CompanyTable 
WHERE 
    CompanyName IN ('Subway','A & W','Pizzahut').

我不知道如何在这里使用参数。

3 个答案:

答案 0 :(得分:3)

您可以采取一些路线

  • classic ”传递分隔的字符串参数,并使用数据库中用户定义的表值函数将字符串转换为表格。然后您可以加入该表进行过滤。

类似的东西(这将返回INT数据类型的表,只需稍微更改代码VARCHAR

CREATE function [dbo].[csl_to_table] ( @list nvarchar(MAX) )
RETURNS @list_table TABLE ([id] INT)
AS
BEGIN
    DECLARE     @index INT,
                @start_index INT,
                @id INT

    SELECT @index = 1 
    SELECT @start_index = 1
    WHILE @index <= DATALENGTH(@list)
    BEGIN

        IF SUBSTRING(@list,@index,1) = ','
        BEGIN

                SELECT @id = CAST(SUBSTRING(@list, @start_index, 
                        @index - @start_index ) AS INT)
                INSERT @list_table ([id]) VALUES (@id)
                SELECT @start_index = @index + 1
        END
        SELECT @index  = @index + 1
    END
    SELECT @id = CAST(SUBSTRING(@list, @start_index, 
            @index - @start_index ) AS INT)
    INSERT @list_table ([id]) VALUES (@id)
    RETURN
END
  • 您可以在.NET代码中使用循环来构建IN子句。但请记住,您只能使用256个参数(IIRC)。

像这样(a la this answer

string[] tags = new string[] { "Subway","A & W","Pizzahut" };
string cmdText = 
    "SELECT CompanyId FROM CompanyTable WHERE CompanyName IN ({0})";

string[] paramNames = tags.Select(
    (s, i) => "@tag" + i.ToString()
).ToArray();

string inClause = string.Join(",", paramNames);
using (SqlCommand cmd = new SqlCommand(string.Format(cmdText, inClause))) {
    for(int i = 0; i < paramNames.Length; i++) {
       cmd.Parameters.AddWithValue(paramNames[i], tags[i]);
    }
}

答案 1 :(得分:0)

这是存储过程吗?

按参数,是指存储过程参数吗?

当您说要使用名称列表的参数时,是指您想使用整个列表中的一个参数,还是要为每个字符串使用一个参数?

假设这是一个存储过程,并且你想使用它的参数,并且你想使用整个列表的单个参数(varchar)(例如:''Subway','A&amp; W ',.....“)

以下是您可以做的事情: 看看我今天对这个问题的回答: SQL - using a variable for an IN clause

答案 2 :(得分:0)

在SSRS中,您可以编写IN(@list),但在常规T-SQL中,您不能。

但是你可以在2008年将一个表值参数传递给一个proc,这样你就可以很容易地处理它(如果你愿意,也可以使用连接)。