2013-04-16 3 views
0

Я пытаюсь построить SQL-запрос, используя StringBuilder, и я застреваю, пытаясь сделать часть предложения WHERE.Построение SQL IN-оператора из элемента управления списком

У меня есть список с множеством значений и позволяет несколько вариантов выбора. Мне нужно перебирать выбранные элементы и поместить затем в IN заявление как ...

WHERE SOME_FIELD IN ('Value','NextValue','AnotherValue') 

до сих пор я написал код, как это ...

if (lstSalesGroup.SelectedItem != null) 
{ 
    selectQuery.Append("AND SALES_GROUP IN ("); 
    foreach (ListItem item in lstSalesGroup.Items) 
    { 
     if (item.Selected) 
      selectQuery.Append("'" + item.Value + "',"); 
    } 
    selectQuery.Append(")"); 
} 

Мне нужно проверить если элемент является последним в цикле, чтобы он не помещал «,» перед закрытием «)».

Как я могу это сделать? Или, если есть лучший способ построить эту часть запроса, пожалуйста, предлагайте, я все еще учился, мы все должны что-то начать! :)

В конце концов это будет запрос на поиск деталей.

Заранее спасибо

ответ

4

Пара способов для этого.

Вы можете использовать string.TrimEnd, чтобы удалить лишнюю запятую из строки или вы можете создать новую строку, используя string.Join как

string InPartQuery = string.Join(",", lstSalesGroup.Items 
              .Cast<ListItem>() 
              .Where(t => t.Selected) 
              .Select(r => "'" + r.Value + "'")); 
+0

+1 для laconic LINQ, но вы должны добавить фильтр по выбранным предметам –

+1

@lazyberezovsky, спасибо, что указали об этом :) – Habib

+0

Это замечательно! Большое спасибо @Habib :) Что такое лаконичный LINQ? как он отличается от обычного LINQ? – Stuart

0

Попробуйте это:

if (lstSalesGroup.SelectedItem != null) 
{ 
    selectQuery.Append("AND SALES_GROUP IN ("); 
    var local = lstSalesGroup.Items.Where(c => c.Selected) 
         .Select(c => "'"+c.Value+"'") 
         .Aggregate((c,n) => c+ ", "+n); 

    selectQuery.Append(local);    
    selectQuery.Append(")"); 
} 

Посмотрите на this пример для получения дополнительной информации о методе .Aggragate(...)

+0

Это будет производить правильный результат, но я думаю, что агрегирование строки без 'StringBuilder 'создаст много ненужных строк. Простой 'String.Join' будет лучше здесь –

+0

@lazyberezovsky Я согласен. 'string.Join' проще. Я просто не думал об этом :) Мой ум «linq'ed» –

+1

Вот подсказка, как остаться с LINQ, но избегайте беспорядочной памяти со строками 'Aggregate (new StringBuilder(), (sb, s) => sb.Append (s), sb => sb.ToString()) ':) –

1

Вы можете использовать String.Join с некоторыми Linq

Для Я понял код в переменных.

if (lstSalesGroup.SelectedItem != null) 
{ 
    var queryStr = "AND SALES_GROUP IN ({0})"; 
    var selectedItemValues = (from itm in lstSalesGroup.Items.Cast<ListItem>() 
           where itm.Selected 
           select String.Format("'{0}'", itm)); 
    selectQuery.Append(String.Format(queryStr, String.Join(",", selectedItemValues))); 
} 
+0

Вам не хватает котировок вокруг значений. И я не уверен, что 'itm' не будет' object' типа –

+1

@lazyberezovsky Спасибо, я пропустил это, поэтому я его отредактировал. Теперь должно быть хорошо. – Silvermind

+0

Да, теперь это правильно –

1

Попробуйте использовать LINQ

selectQuery.Append("AND SALES_GROUP IN ("); 

selectQuery.Append(string.Join(",", lstSalesGroup.Items.Select(i => "'" + i.Value + "'")));  

selectQuery.Append(")"); 

Это позволит решить вашу проблему, но у вас есть проблемы с инъекции SQL здесь. Я бы настоятельно советовал вам использовать параметры в вашем запросе.

+0

Спасибо, что указали это. Я думал, что это безопасно от инъекций, если я программно заполняю варианты выбора? – Stuart

+2

Это распространенная ошибка, но здесь существует потенциальный риск для SQL-инъекции. Представьте, что кому-то удалось получить значение «»). Отбросьте таблицу SomeTable; - «в свой список. Вы можете увидеть, как будет выглядеть ваш последний запрос? =) – user707727

+0

... что-то вроде моего P45 !! Я поставлю все конечные значения в параметры. благодаря! – Stuart

0
Dim s As String = "'" 
    For i = 0 To ListBox1.Items.Count - 1 
     s = s & ListBox1.Items.Item(i) & "','" 
    Next 
+0

Это на самом деле не похоже C# ;-) И, пожалуйста, предоставьте некоторое объяснение, чтобы улучшить ваш ответ. – d4Rk

+0

Вопрос о C#, это Visual Basic. –

 Смежные вопросы

  • Нет связанных вопросов^_^