2009-11-15 82 views
2

在C#中,我有一個整數數組,代表SQL Server中表中行的主鍵。我需要通過執行一個Select命令從SQL Server中選擇所有這些行 - 最好通過存儲過程。如何從一個id數組中獲取一組行?

有可能是從幾個到上百個ID的數組中,並解決方案需要SQL Server 2005和2008

什麼是最好/最有效的方式做到這一點的工作嗎?

我目前有一個解決方案,其中我將包含ID的逗號分隔列表的字符串傳遞給SQL Server,然後在此基礎上生成SELECT語句。我希望有一個更好的方法,不涉及動態生成SQL語句。

回答

2

Linq2SQL通過執行where idList.Contains(record.id)來支持這個;在ADO.Net沒有與TableAdapter的沒有真正的解決辦法,但這篇文章應該得到它的工作:

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

+0

不幸的是,我不能使用Linq2SQL。但是,當我需要支持SQL Server 2005時,XML方法似乎是實現它的方法。 – driis 2009-11-15 16:20:50

1

您可以創建一個存儲過程,這需要一個TABLE數據類型作爲輸入參數,並加入此參數你的數據表。在C#代碼中,創建一個包含ID的DataTable,並將此DataTable作爲參數傳遞給存儲過程。

下面是關於如何做到這一點的詳細介紹:http://msdn.microsoft.com/en-us/library/bb675163.aspx

編輯:我不知道這是否與SQL Server 2005或僅與2008年......

+0

不幸的是,2005年不支持表值參數,而且我確實需要保持與SQL Server 2005的兼容性。 – driis 2009-11-15 16:19:46

1

我有很多使用SQL Server的OPENXML成功。使用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 – 2009-11-15 17:23:17

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