SQL Выберите, где значения в списке <string> - PullRequest
10 голосов
/ 02 марта 2009

Есть ли способ создать запрос к источнику данных (может быть sql, oracle или access) с предложением where, указывающим на ArrayList или List?

пример:

Select * from Table where RecordID in (RecordIDList)

Я видел несколько способов сделать это с Linq, но я бы не стал прибегать к этому, если этого можно избежать.

Ответы [ 8 ]

12 голосов
/ 02 марта 2009

Вы можете использовать String.Join. Попробуйте что-то вроде этого:

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

В качестве дополнительного примечания это не защитит вас от внедрения SQL - надеюсь, этот пример укажет вам правильное направление.

7 голосов
/ 02 марта 2009

Линк к кв. RecordList должен быть List<T>, а не ArrayList или IList<T>

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

Это сгенерирует sql с параметрами:

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

Linq сгенерирует столько параметров, сколько необходимо. Некоторые реализации базы данных ограничены числом параметров, которые могут быть приняты. Ограничение SqlServer2005 составляет немногим более 2000 параметров ... поэтому не используйте список, содержащий более 2000 элементов.

6 голосов
/ 02 марта 2009

Я сделал только то, что вы пытаетесь сделать со списком через запятую

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

или откуда результаты берутся отдельно

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

Я почти уверен, что ты не сможешь добиться того, чего хочешь ...

4 голосов
/ 02 марта 2009

Вы можете перебрать свой массив и добавить параметр в ваш SQL для каждого. Это поможет вам внедрить SQL, но убедитесь, что вы используете StringBuilder, а не последовательную конкатенацию при создании оператора SQL.

, например

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.
}
1 голос
/ 02 марта 2009

Вы можете написать пользовательскую функцию с табличным значением, которая берет список идентификаторов и создает таблицу, а затем снова присоединяет результат этой функции. Эта статья Эрланда Соммарского описывает, как это сделать.

Или вы можете использовать параметры таблицы, новые в SQL Server 2008 (я думаю).

Или, как сказал Ману, вы можете использовать XML.

Однако я не советую использовать подход IN String.Join в принятом ответе, поскольку это все равно, что запрашивать инъекцию SQL.

0 голосов
/ 02 марта 2009

Обратите внимание, что 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 - это то, что вам следует использовать в настоящее время, если вы хотите реализовать такую ​​архитектуру.

Кроме того, если вы используете другой запрос на выборку (как предлагает GordonB) для предложения «in», было бы лучше использовать «существующие» вместо «in», например:

select * from tablename where exists (select id from othertablename where fieldtype=1)
0 голосов
/ 02 марта 2009

Используя Linq to SQL, и я предполагаю, что Entity Framework вы можете сделать следующее:

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

Будет работать как с List <>, так и с ArrayList, поскольку они оба реализуют IEnumerable.

Linq и Lambdas требуют, чтобы вы изменили метод Contains, но он работает и создает предложение SQL "IN ()".

0 голосов
/ 02 марта 2009

Если вы используете динамический SQL, вы можете отправить содержимое скобок в виде списка, разделенного запятыми. В противном случае вы можете использовать переменную XML для отправки нескольких значений. Смотри http://vyaskn.tripod.com/passing_arrays_to_stored_procedures.htm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...