Динамическое создание запроса SQL со многими AND и OR - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть приложение. NET Forms, которое представляет собой систему отслеживания производства. У меня есть DataGridView и несколько ListViews с проверяемыми элементами для фильтрации таблицы данных. Фильтры включают номер детали, номер заряда, текущее местоположение и т. Д. c. Есть 9 ListViews и 2 TextBox (входные данные тщательно проверены). Сейчас я использую For l oop для отмеченных элементов, чтобы добавить их в предложение Where запроса SQL. Я обеспокоен тем, что мои запросы могут стать очень неэффективными. Запрос включает в себя 13 объединений, а основная таблица, к которой я обращаюсь, содержит около 2000 строк, но я вижу, что в следующие несколько лет она достигнет 100 000.

string query = @"SELECT top 1000 [column names] FROM [table names and joins] ";  

List<string> filters = new List<string>();

//
// Part Number 
//
if (ListViewPartNumber.CheckedItems.Count != 0)
{
    string PartNumberFilterString = " ( ";
    for (int i = 0; i < ListViewPartNumber.CheckedItems.Count; i++)
    {
        int PN_ID = ListViewPartNumber.GetCheckedValue( i );
        PartNumberFilterString += "SubAssembliesTable.PN_ID  = " + PN_ID;
        if ( i < ListViewPartNumber.CheckedItems.Count - 1 ) 
            PartNumberFilterString += " OR ";
    }
    PartNumberFilterString += " ) ";
    filters.Add(PartNumberFilterString);
}

Добавляется в список фильтров для каждого списка, в котором отмечены элементы. Затем он объединяет их в одну строку для запроса к базе данных.

//
// Create filter string
//
for ( int i = 0 ; i < filters.Count ; i++ )
{
    if ( i == 0 ) query += "\r\n where ";
    query += filters[ i ];
    if ( i < filters.Count - 1 ) query += " AND ";
}

query += " \r\nORDER BY [ColumnName]  desc ";

Работает нормально, проблем с производительностью не замечено, но я беспокоюсь, что делаю это совершенно неправильно. Запрос может закончиться десятками AND и OR.

1 Ответ

0 голосов
/ 07 апреля 2020

Похоже, что списки содержат строки из нескольких ссылочных таблиц

  • проверяют, проиндексированы ли соответствующие столбцы внешних ключей (исключая неселективные столбцы, такие как "sex" или "enabled", которые имеют 2- 3 уникальных значения)
  • используйте фрагменты кода, такие как SubAssembliesTable.PN_ID IN (id1, id2, .. idN) вместо SubAssembliesTable.PN_ID=id1 OR SubAssembliesTable.PN_ID=id2 ...
  • , используйте скорее параметры запроса, чтобы избежать SQL атаки с использованием инъекций
  • добавить некоторые тесты производительности чтобы обеспечить требуемое время отклика в параллельном режиме

Вы также можете посмотреть книгу " Программирование с базами данных ", в которой содержатся более подробные пояснения по вышеуказанным темам.

...