2009-11-15 4 views
2

В C# у меня есть массив целых чисел, которые представляют первичные ключи строк в таблице на SQL Server. Мне нужно выбрать все эти строки из SQL Server, выполнив одну команду Select - желательно с помощью хранимой процедуры.Как получить набор строк из массива id?

Там может быть от нескольких до сотен идентификаторов в массиве, и решение должно работать на SQL Server 2005 и 2008.

Что является лучшим/наиболее эффективный способ сделать это?

В настоящее время у меня есть решение, где я передаю строку, содержащую список идентификаторов для SQL Server, и затем генерирую инструкцию SELECT на основе этого. Я надеюсь, что есть лучший способ, который не включает динамическое генерирование операторов SQL.

ответ

2

Linq2SQL поддерживает это, делая where idList.Contains(record.id); В ADO.Net нет никакого реального решения с TableAdapters, но эта статья должна заставить его работать:

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

+0

Я не могу использовать Linq2SQL, к сожалению. Но подход XML, как представляется, является способом сделать это, когда мне нужно поддерживать SQL Server 2005. – driis

1

Вы можете создать хранимую процедуру, которая принимает тип таблицы данных в качестве входного параметра и соединяющую этот параметр с вашей таблицы данных. В коде C# вы создаете DataTable, содержащий идентификаторы, и передаете этот DataTable в хранимую процедуру в качестве параметра.

Вот подробное описание того, как сделать это: http://msdn.microsoft.com/en-us/library/bb675163.aspx

EDIT: Я не уверен, если это работает с SQL Server 2005 или только с 2008 ...

+0

К сожалению, параметры табличного значения не поддерживаются в 2005 году, и мне действительно нужно оставаться совместимыми с SQL Server 2005. – driis

1

У меня было много успеха с использованием OPENXML с SQL Server. Перейдите в неограниченный массив значений, используя либо TEXT, либо типы данных XML, затем используйте этот параметр в качестве соединения или подвыборки, чтобы вернуть нужные данные.

Я использовал это, поскольку SQL Server 2000 был выпущен, и он работает как чемпион.

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

Я предпочитаю это подход.Я уже писал об этом несколько раз недавно: http://sqlblog.com/blogs/aaron_bertrand/archive/2009/08/01/processing-a-list-of-integers-my-approach.aspx http: // sqlblog .com/блог/aaron_bertrand/Архив/2009/08/06/более-на-расщепляющих-листов-заказ разделитель предотвращающий-дубликаты, и сохраняющие-order.aspx –

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) 
) 
Смежные вопросы