SQL Выберите, где значения в List <string>

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

пример:

Select * from Table where RecordID in (RecordIDList)

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

Ответ 1

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

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

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

Ответ 2

Linq to Sql. 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 элементами.

Ответ 3

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

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

Вы можете выполнить итерацию по вашему массиву и добавить для каждого параметра для каждого из них. Это заставит вас использовать 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.
}

Ответ 5

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

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

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

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

Ответ 6

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

Ответ 7

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

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

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

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

Ответ 8

Обратите внимание: Linq to SQL = dead, Источник: http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq-to-entities-roadmap.aspx

Структура Entity - это то, что вы должны использовать в настоящее время, если вы хотите реализовать такую ​​архитектуру.

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

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