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)