2009-03-02 13 views
10

Esiste un modo per creare una query su un'origine dati (potrebbe essere sql, oracle o access) con una clausola where che rimanda a un ArrayList o List?SQL Selezionare i valori nell'Elenco <string>

esempio:

Select * from Table where RecordID in (RecordIDList) 

Ho visto alcuni modi per farlo con LINQ, ma preferisco non ricorso ad esso se è evitabile.

risposta

12

È possibile utilizzare String.Join. Provare qualcosa di simile:

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

Come nota a margine questo non protegge contro le SQL injection - speriamo che questo esempio vi punto nella giusta direzione.

+0

La firma per string.join è in realtà (string, string []) in modo che la chiamata sarebbe più correttamente simile string.join ("", list.ToArray()). – mquander

+0

Buona chiamata: l'ho risolto! –

+0

Vorrei andare oltre la tua affermazione "non ti proteggerò dall'iniezione SQL" e dire che queste cose sono la madre di tutte le iniezioni SQL. L'approccio migliore è molto più lavoro, però. – erikkallen

6

ho fatto solo ciò che il vostro cercando di fare con un elenco separato da virgole

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

o dove i risultati provengono da un separato selezionare

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

sono abbastanza sicuro che non è possibile ottenere quello che stai ....

7

Linq a Sql. RecordList dovrebbe essere un List<T>, non un ArrayList o un IList<T>

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

Questo genererà SQL con i parametri:

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

LINQ genera il maggior numero di parametri come sono necessari. Alcune implementazioni del database sono limitate nel numero di parametri che possono essere accettati. Il limite di SqlServer2005 è un po 'più di 2000 parametri ... quindi non usare una lista con più di 2000 elementi.

0

utilizzando LINQ to SQL e presumo Entity Framework è possibile effettuare le seguenti operazioni:

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

usare entrambi Lista <> e ArrayList come entrambi implementano IEnumerable.

Linq e Lambdas richiedono l'inversione del metodo Contains ma funzionano e generano una clausola SQL "IN()".

-4

Si prega di notare LINQ to SQL = morto, Fonte: http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq-to-entities-roadmap.aspx

Entity Framework è quello che si dovrebbe usare al momento se si desidera implementare tale architettura.

Inoltre, se si utilizza un altro query di selezione (come suggerisce GordonB) per il vostro "a" clausola sarebbe meglio usare "esiste" anziché "in", per esempio:

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

JoelHess non ha chiesto informazioni su LinqToSql ... la domanda include Oracle, quindi LinqToSql avrebbe dovuto essere escluso da tale requisito. –

1

È possibile scrivere una funzione definita dall'utente valutata a livello di tabella che accetta un elenco di ID e crea una tabella, quindi unisce nuovamente il risultato di questa funzione. Questo article by Erland Sommarskog descrive come farlo.

Oppure, è possibile utilizzare i parametri della tabella, nuovo in SQL Server 2008 (credo).

Oppure, come ha detto Manu, è possibile utilizzare XML.

Tuttavia, mi sconsiglia di utilizzare l'approccio IN String.Join nella risposta accettata poiché è come chiedere un'iniezione SQL.

4

È possibile scorrere l'array e aggiungere un parametro all'SQL per ciascuno. Questo ti porta in giro con l'iniezione SQL, ma assicurati di utilizzare un oggetto StringBuilder piuttosto che una concatenazione con strign quando crei l'istruzione SQL.

ad es.

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. 
} 
Problemi correlati