Question

Is there a way that I can create query against a data source (could be sql, oracle or access) that has a where clause that points to an ArrayList or List?

example:

Select * from Table where RecordID in (RecordIDList)

I've seen some ways to do it with Linq, but I'd rather not resort to it if it's avoidable.

Was it helpful?

Solution

You could use String.Join. Try something like this:

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

As a side note this will not protect you against SQL injection - hopefully this example will point you in the right direction.

OTHER TIPS

Linq to Sql. RecordList should be a List<T>, not an ArrayList or an IList<T>

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

This will generate sql with parameters:

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

Linq will generate as many parameters as are needed. Some database implementations are limited in the number of parameters that can be accepted. SqlServer2005's limit is a little over 2000 parameters... so don't use a list with more than 2000 elements.

I've only done what your trying to do with a comma separated list

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

or where the results come from a separate select

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

I'm pretty sure you can't achieve what you're after....

You can iterate over your array and add a parameter to your SQL for each. This gets you around SQL injection, but make sure you use a StringBuilder rather than strign concatenation as you build up your SQL statement.

e.g.

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

You can write a table-valued user-defined function that takes a list of IDs and creates a table, then join agains the result of this function. This article by Erland Sommarskog describes how to do it.

Or, you could use table parameters, new in SQL server 2008 (I think).

Or, as Manu said, you can use XML.

However, I advice against using the IN String.Join approach in the accepted answer since it is like asking for SQL injection.

Using Linq to SQL and I assume the Entity Framework you can do the following:

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

Will work with both List<> and ArrayList as they both implement IEnumerable.

Linq and Lambdas require that you reverse the Contains method but it does work and generates a SQL "IN ()" clause.

If you use dynamic SQL, you can send the content of the parentheses as a literal comma-separated list. Otherwise you can use an XML variable for sending multiple values. See http://vyaskn.tripod.com/passing_arrays_to_stored_procedures.htm

Please note Linq to SQL = dead, Source: http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq-to-entities-roadmap.aspx

Entity framework is what you should use currently if you want to implement such architecture.

Furthermore if you are using another select query (like GordonB suggests) for your "in" clause it would be better to use "exists" instead of "in" for example:

select * from tablename where exists (select id from othertablename where fieldtype=1)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top