如何从id的数组中获取一组行?

时间:2009-11-15 15:26:29

标签: c# sql-server ado.net

在C#中,我有一个整数数组,它们代表SQL Server中表中行的主键。我需要通过执行单个Select命令从SQL Server中选择所有这些行 - 最好通过存储过程。

阵列中可能有几个到几百个ID,解决方案需要在SQL Server 2005和2008上运行。

最好/最有效的方法是什么?

我目前有一个解决方案,我将一个包含逗号分隔的id列表的字符串传递给SQL Server,然后根据它生成一个SELECT语句。我希望有一种更好的方法,不涉及动态生成SQL语句。

5 个答案:

答案 0 :(得分:2)

Linq2SQL通过where idList.Contains(record.id)支持这一点;在ADO.Net中,TableAdapter没有真正的解决方案,但是本文应该让它工作:

http://support.microsoft.com/kb/555266/en-us

答案 1 :(得分:1)

您可以创建一个存储过程,该过程将TABLE数据类型作为输入参数,并将此参数与数据表连接。在C#代码中,创建一个包含ID的DataTable,并将此DataTable作为参数传递给存储过程。

以下是有关如何执行此操作的详细说明:http://msdn.microsoft.com/en-us/library/bb675163.aspx

编辑:我不确定这是适用于SQL Server 2005还是仅适用于2008 ...

答案 2 :(得分:1)

我使用OPENXML和SQL Server取得了很大的成功。使用TEXT或XML数据类型传入无限数组的值,然后将该参数用作连接或子选择以返回所需的数据。

我已经使用过这个,因为SQL Server 2000已经发布,它就像冠军一样运行。

答案 3 :(得分:1)

一种选择是将列表作为xml文档传递。使用.NET序列化很容易创建这样的文档:

var yourList = new List<int>() { 1, 2, 3 };
using (var stream = new MemoryStream())
using (var writer = XmlWriter.Create(stream))
{
    new XmlSerializer(yourList.GetType()).Serialize(writer, yourList);
    var xmlEncodedList = Encoding.UTF8.GetString(stream.ToArray());
}

您可以在SQL Server中解析文档,如:

declare @list xml
set @list = '<?xml version="1.0" encoding="utf-8"?><ArrayOfInt 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<int>1</int><int>2</int><int>3</int></ArrayOfInt>'

select list.a.value('.','int')
from @list.nodes('/ArrayOfInt/int') as list(a)

现在您已将XML更改为查询,您可以使用它执行任何操作。将其存储在临时表中,或将其加入另一个表中。这是一个从表中检索特定行的示例过程:

create procedure testproc(@list as xml)
as
select *
from TheTable
where ID in (
    select list.a.value('.','int')
    from @list.nodes('/ArrayOfInt/int') as list(a)
)

答案 4 :(得分:0)

我和你在一起。使用逗号分隔的字符串并不是一个糟糕的方法。但您可以创建Table-Valued Function来动态生成表格并将其与目标表格连接。

Create Function [dbo].[Split]
(
    @Array          nvarchar(4000),
    @Separator      char,
    @ToLower        bit = 0
)
Returns 
@Result Table 
(
    ItemKey     int Identity(1, 1) Not Null,
    ItemValue       nvarchar(256) NULL
)
AS
BEGIN

    Declare @Index int,
            @Value nvarchar(256)

    Select @Index = 0
    Select @Value = Null

    While (1 = 1)
    Begin

        Select @Index = CharIndex(@Separator, @Array)

        If (@Index = 0)
        Begin
            Insert Into @Result Values (LTRIM(RTRIM(Case @ToLower When 1 Then Lower(@Array) Else @Array End)))
            Break
        End

        Select @Value = SubString(@Array, 0, @Index)

        Insert Into @Result Values (LTRIM(RTRIM(Case @ToLower When 1 Then Lower(@Value) Else @Value End)))

        Select @Array = Right(@Array, Len(@Array) - @Index)

    End

    Return

END

Select *
from dbo.TargetTable tt, dbo.Split('101, 102, 103', ',', 0) r
Where (tt.PrimaryKey = r.ItemValue)