20

例如。我可以写这样的代码吗:

public void InactiveCustomers(IEnumerable<Guid> customerIDs)
{
    //...
    myAdoCommand.CommandText =
        "UPDATE Customer SET Active = 0 WHERE CustomerID in (@CustomerIDs)";
    myAdoCommand.Parameters["@CustomerIDs"].Value = customerIDs;
    //...
}

我知道的唯一方法是加入我的 IEnumerable,然后使用字符串连接来构建我的 SQL 字符串。

4

6 回答 6

17

通常,您执行此操作的方法是传入一个逗号分隔的值列表,然后在您的存储过程中,解析该列表并将其插入到一个临时表中,然后您可以将其用于连接。从Sql Server 2005 开始,这是处理需要保存数组的参数的标准做法。

这是一篇关于处理此问题的各种方法的好文章:

将列表/数组传递给 SQL Server 存储过程

但是对于Sql Server 2008,我们最终将表变量传递到过程中,首先将表定义为自定义类型。

本文对此(以及更多 2008 功能)有很好的描述:

SQL Server 2008 中新的 T-SQL 可编程功能简介

于 2008-09-22T12:52:25.860 回答
5

您可以使用SQL 2008。出来的时间不长,但它是可用的。

于 2008-09-22T12:56:05.073 回答
2

正如评论中提到的,Erland Sommarskog 写了一系列关于这个主题的文章(链接到下面)。文章很透彻,可以作为参考资料。虽然它们特定于 SQL Server (T-SQL),但其中提到的一些技术也可能适用于其他 RDBMS(例如使用XML数据类型):

于 2015-06-29T08:07:47.980 回答
1

您可以使用 xml 参数类型:

CREATE PROCEDURE SelectByIdList(@productIds xml) AS

DECLARE @Products TABLE (ID int) 

INSERT INTO @Products (ID) SELECT ParamValues.ID.value('.','VARCHAR(20)')
FROM @productIds.nodes('/Products/id') as ParamValues(ID) 

SELECT * FROM 
    Products
INNER JOIN 
    @Products p
ON    Products.ProductID = p.ID

http://weblogs.asp.net/jgalloway/archive/2007/02/16/passing-lists-to-sql-server-2005-with-xml-parameters.aspx

于 2008-09-22T13:00:21.817 回答
-2

没有。参数就像遵循第一范式的 SQL 值,基本上只能有一个...

您可能知道,生成 SQL 字符串是有风险的业务:您让自己面临SQL 注入攻击。只要您正在处理真正的 GUID,您应该没问题,但否则您需要确保清理您的输入。

于 2008-09-22T12:29:05.433 回答
-2

您不能将列表作为单个 SQl 参数传递。您可以 string.Join(',') 诸如“0000-0000-0000-0000, 1111-1111-1111-1111”之类的 GUIDS,但这会增加数据库开销并且确实不是最佳的。而且您必须将整个字符串作为单个连接的动态语句传递,您不能将其添加为参数。

问题:

您从哪里获得代表不活跃客户的 ID 列表?

我的建议是用不同的方式处理这个问题。将所有这些逻辑移到数据库中,例如:

    Create procedure usp_DeactivateCustomers 
    @inactive varchar(50) /*or whatever values are required to identify inactive customers*/
    AS    
    UPDATE Customer SET c.Active = 0 
    FROM Customer c JOIN tableB b ON c.CustomerID = b.CustomerID 
    WHERE b.someField = @inactive

并将其称为存储过程:

public void InactiveCustomers(string inactive)
{
    //...
    myAdoCommand.CommandText =
        "usp_DeactivateCustomers";
    myAdoCommand.Parameters["@inactive"].Value = inactive;
    //...
}

如果数据库中存在 GUID 列表,我为什么需要:找到它们;将它们放在一个通用列表中;将列表展开为 CSV/XML/Table 变量,只是为了再次将它们呈现回 DB ????? 他们已经在那里了!我错过了什么吗?

于 2008-09-22T12:31:09.047 回答