2009-03-02 33 views
10

Có cách nào để tôi có thể tạo truy vấn đối với nguồn dữ liệu (có thể là sql, oracle hoặc access) có mệnh đề where trỏ đến ArrayList hoặc List không?SQL Chọn giá trị trong Danh sách <string>

dụ:

Select * from Table where RecordID in (RecordIDList) 

Tôi đã nhìn thấy một số cách để làm điều đó với LINQ, nhưng tôi không muốn dùng đến nó nếu nó có thể tránh được.

Trả lời

12

Bạn có thể sử dụng String.Join. Hãy thử một cái gì đó như thế này:

String query = "select * from table where RecordId in ({0});"; 
String formatted = String.Format(query, String.Join(",", list.ToArray())); 

Lưu ý rằng điều này sẽ không bảo vệ bạn chống lại SQL injection - hy vọng ví dụ này sẽ chỉ cho bạn đi đúng hướng.

+0

Chữ ký cho chuỗi.Join thực ra là (chuỗi, chuỗi []) để cuộc gọi trông giống hệt như chuỗi.Join (",", list.ToArray()). – mquander

+0

Cuộc gọi tốt - Tôi đã sửa nó! –

+0

Tôi sẽ đi xa hơn tuyên bố của bạn "sẽ không bảo vệ bạn chống lại SQL injection" và nói rằng những điều này là mẹ của tất cả các tiêm SQL. Tuy nhiên, cách tiếp cận tốt hơn là làm việc nhiều hơn. – erikkallen

6

tôi đã chỉ làm những gì bạn đang cố gắng để làm với một danh sách dấu phẩy tách

Select * from Table where RecordID in (1,2,34,45,76,34,457,34) 

hoặc trong trường hợp kết quả đến từ một riêng biệt chọn

Select * from Table where RecordID in (select recordId from otherTable where afieldtype=1) 

Tôi khá chắc chắn rằng bạn không thể đạt được những gì bạn đang theo dõi ....

7

LINQ to SQL. RecordList phải là một List<T>, không phải là một ArrayList hoặc một IList<T>

IEnumerable<TableRow> query = 
    from t in db.Table 
    where RecordList.Any(r => t.RecordId == r) 
    select t; 

Điều này sẽ tạo sql với các thông số:

SELECT * 
FROM Table 
WHERE RecordId in (@p0, @p1, @p2, @p3, @p4) 

LINQ sẽ tạo ra càng nhiều thông số như là cần thiết. Một số triển khai cơ sở dữ liệu bị hạn chế về số lượng tham số có thể được chấp nhận. Giới hạn của SqlServer2005 là một ít hơn 2000 thông số ... do đó, không sử dụng một danh sách với hơn 2000 yếu tố.

0

Sử dụng LINQ to SQL và tôi giả định khung Entity bạn có thể làm như sau:

dataContext.Table.Where(t => RecordIDList.Contains(t.RecordID)); 

Sẽ làm việc với cả hai Danh sách <> và ArrayList là cả hai đều thực hiện IEnumerable.

LINQ và Lambdas yêu cầu bạn đảo ngược phương pháp Chứa nhưng nó hoạt động và tạo ra mệnh đề SQL "IN()".

-4

Xin lưu ý LINQ to SQL = chết, Nguồn: http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq-to-entities-roadmap.aspx

khung Entity là những gì bạn cần hiện đang sử dụng nếu bạn muốn thực hiện kiến ​​trúc như vậy.

Hơn nữa, nếu bạn đang sử dụng một truy vấn chọn (như GordonB gợi ý) cho bạn "trong" khoản đó sẽ là tốt hơn để sử dụng "tồn tại" thay vì "trong" ví dụ:

select * from tablename where exists (select id from othertablename where fieldtype=1) 
+0

JoelHess đã không hỏi về LinqToSql ... câu hỏi bao gồm Oracle, vì vậy LinqToSql nên đã được loại trừ bởi yêu cầu đó. –

1

Bạn có thể viết một hàm do người dùng định nghĩa do người dùng định nghĩa có một danh sách các ID và tạo một bảng, sau đó tham gia lại kết quả của hàm này. article by Erland Sommarskog mô tả cách thực hiện.

Hoặc, bạn có thể sử dụng tham số bảng, mới trong SQL Server 2008 (tôi nghĩ).

Hoặc, như Manu đã nói, bạn có thể sử dụng XML.

Tuy nhiên, tôi khuyên không nên sử dụng chuỗi IN.Chuyển tiếp tiếp cận trong câu trả lời được chấp nhận vì nó giống như yêu cầu tiêm SQL.

4

Bạn có thể lặp qua mảng của mình và thêm tham số vào SQL cho từng mảng. Điều này sẽ giúp bạn xung quanh việc tiêm SQL, nhưng hãy chắc chắn rằng bạn sử dụng một StringBuilder thay vì kết nối strign khi bạn xây dựng câu lệnh SQL của mình.

ví dụ:

StringBuilder sql = new StrignBuilder("select * from Table where "); 
for (int i = 0; i < RecordIDLis.Length; i++) 
{ 
    if (i > 0) sql.Append (" OR "); 
    sql.Append(" RecordID = @param" + i.ToString() + " "); 
    IDbDataParameter param = new Param(); 
    param.value etc. 
} 
Các vấn đề liên quan