开发者

How to get a set of rows from an array of id's?

In C#, I have an array of integers, that represent the primary keys of rows in a Table in SQL Server. I need to select all these rows from SQL Server by executing a single Select command - preferably through a stored procedure.

There may be from a few to hundreds of ID's in the array, and the solution needs to work on SQL Server 2005 and 2008.

What is the best/most efficient way to do this ?

I currently have a solution, where I pass a string containing a comma-separated list of the ids to SQL Server, and then generating a SELECT statement based on this. I am hoping there is a better way, that do not involve dynamical开发者_开发问答ly generating the SQL statements.


Linq2SQL supports this by doing a where idList.Contains(record.id); In ADO.Net there is no real solution with TableAdapters, but this article should get it working:

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


You can create a stored procedure which takes a TABLE data type as an input parameter and joins this parameter with your data table. In your C# code, you create a DataTable containing the IDs and pass this DataTable to your stored procedure as a parameter.

Here's a detailed description on how to do this: http://msdn.microsoft.com/en-us/library/bb675163.aspx

EDIT: I'm not sure if this works with SQL Server 2005 or only with 2008...


I've had a lot of success using OPENXML with SQL Server. Pass in an unlimited array of values using either TEXT or XML data types, then use that parameter as a join or sub-select to return the data you want.

I've used this since SQL Server 2000 was released and it runs like a champ.


One option is to pass the list as an xml document. Such a document is easy to create with .NET serialization:

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());
}

You can parse the document in SQL Server like:

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)

Now that you've changed the XML into a query, you can do anything with it. Store it in a temporary table, or join it on another table. Here's an example procedure that retrieves specific rows from a table:

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)
)


I'm with you. Using a comma delimited string is not a bad approach. But you can create a Table-Valued Function to generate a table on the fly and join it with your target table.

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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜