Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# и базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
 
mas9
1 / 1 / 3
Регистрация: 30.10.2015
Сообщений: 15
#1

Поиск данных в бд по некоторым параметрам - C#

13.06.2017, 14:03. Просмотров 602. Ответов 17
Метки нет (Все метки)

Здравствуйте, прикрутил БД к c#, нужно реализовать поиск в бд. Пользователь может искать по Фамилии, Имени, Отчеству, Дате регистрации либо Периоду подачи декларации. Пользователь может ввести все данные для поиска, либо ввести только некоторые.
Как мне реализовать выборку по WHERE в запросе, т.к. я не знаю точно какие данные ввёл пользователь. Через IF делать проверки не вариант, т.к. слишком много вариантов может быть( 1 2 3 4 5, 1 3 5, 2 4, 1 2 3, 1 2, 2 3 и т.д.).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.06.2017, 14:03
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Поиск данных в бд по некоторым параметрам (C#):

Поиск по таблице по параметрам
Здравствуйте, дали задание для шарпа, раньше с ним дела не имел, поставил на...

Поиск по нескольким параметрам в DataGridView с данными из БД Access
Есть задание, но я напишу лишь ту часть которую не могу сделать Нужно сделать...

Поиск в базе SQL Server по нескольким параметрам
Имеется форма поиска. в ней можно осуществлять поиск только по одному...

Выборка данных по двум параметрам (пол, возраст)
Доброго времени суток! :) Ребята, подскажите как грамотно решить такую задачу....

Вопрос по некоторым параметрам при тестировании HDD
Всем привет тут попросили об одной вещи: Хард тестили программой HDD,и хотят...

Поиск в массиве данных по заданным параметрам
Добрый день Я изучаю программирование на Objective-C и у меня возникла...

17
Shogun31337
494 / 478 / 203
Регистрация: 02.11.2016
Сообщений: 1,439
Завершенные тесты: 2
13.06.2017, 17:15 #2
Цитата Сообщение от mas9 Посмотреть сообщение
нужно реализовать поиск в бд
Где искать? В DataSet или в самой БД?
Цитата Сообщение от mas9 Посмотреть сообщение
Пользователь может искать по Фамилии, Имени, Отчеству, Дате регистрации либо Периоду подачи декларации. Пользователь может ввести все данные для поиска, либо ввести только некоторые.
Поле поиска одно на все поля?
0
hoolygan
264 / 271 / 74
Регистрация: 21.06.2016
Сообщений: 1,060
13.06.2017, 17:45 #3
Самое главное -непонятно какая СУБД.
Если есть варианты с хранимыми процедурами и динамическим кодом (напр MS SQL) - то проблема решаема небольшой кровью.
В общем - данные для понимания в студию.
0
mas9
1 / 1 / 3
Регистрация: 30.10.2015
Сообщений: 15
14.06.2017, 08:46  [ТС] #4
Ищем в DataSet, БД прикручена из Access.
По поводу поиска.
Допустим есть запись в БД Инспектор с данными: Валуев Игорь Андреевич 12.06.2010 Орг
При поиске если я ввиду все 5 данных, либо допустим только Валуев 12.06.2010, то эта запись должна отобразиться.
0
hoolygan
264 / 271 / 74
Регистрация: 21.06.2016
Сообщений: 1,060
14.06.2017, 11:14 #5
mas9, а куда вводить? все в одно поле? А каким тогда образом программа поймет, что к чему относится?
Или же датасет - это по сути 1 столбик со всеми данными?
Опять же - недостаточно информации для понимания.
Нужны хотя бы скрины, что ли что и как выводится, и что и куда вводить? А то это гадание на кофейной гуще получается.
0
mas9
1 / 1 / 3
Регистрация: 30.10.2015
Сообщений: 15
14.06.2017, 12:35  [ТС] #6
Вот окна с которыми работаю на данный момент.
0
Миниатюры
Поиск данных в бд по некоторым параметрам  
Изображения
 
Shogun31337
494 / 478 / 203
Регистрация: 02.11.2016
Сообщений: 1,439
Завершенные тесты: 2
14.06.2017, 22:53 #7
Цитата Сообщение от mas9 Посмотреть сообщение
Допустим есть запись в БД Инспектор с данными: Валуев Игорь Андреевич 12.06.2010 Орг
При поиске если я ввиду все 5 данных, либо допустим только Валуев 12.06.2010, то эта запись должна отобразиться.
А если есть Валуев Игорь Андреевич и Петров Петр Петрович, а пользователь вводит Валуев Петр, должно найтись 2 человека или ни одного?

Добавлено через 3 минуты
И, если пользователь ввел неполное значение, например Валу, должен Валуев найтись?
0
mas9
1 / 1 / 3
Регистрация: 30.10.2015
Сообщений: 15
15.06.2017, 11:14  [ТС] #8
Про неполное не обязательно.
Если пользователь ввёл два или три поля, то совпадения должны быть по всем.
Т.е. в вашем варианте не должно найти никого
0
Shogun31337
494 / 478 / 203
Регистрация: 02.11.2016
Сообщений: 1,439
Завершенные тесты: 2
15.06.2017, 17:11 #9
Ну, тогда задача решается достаточно просто. Делаете Split входной строки по пробелу, получая при этом массив строк для поиска. Затем, рекурсивно передаете каждую из этих строк в запрос на выборку, используя результат запроса как входную таблицу для следующей строки из массива. Соответственно, на выходе у Вас будет таблица с найденными записями (ну или пустая таблица). А эту выходную таблицу уже можно будет использовать для отображения результатов поиска. Для выборки используйте Linq to DataSet.

Вот накидал код на скорую руку...
Сама функция поиска:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        static DataTable Search(DataTable inputTable, string[] searchStrings, int step = 0)
        {
            string searchString = searchStrings[step];
            DataTable queryTable = new DataTable();
            var query = inputTable
                .AsEnumerable()
                .Where(row => 
                row.Field<string>("LName") == searchString || 
                row.Field<string>("FName") == searchString ||
                row.Field<string>("MName") == searchString ||
                row.Field<DateTime>("Date").ToShortDateString() == searchString);
            if (query.Any())
                queryTable = query.CopyToDataTable(); 
            if (queryTable.Rows.Count > 0 && step < searchStrings.Length - 1)
                Search(queryTable, searchStrings, ++step);
            return queryTable;
        }

Применение:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
        static void Main(string[] args)
        {
            CreateDataTable();
            string queryString = Console.ReadLine();
            string[] s = queryString.Split(' ');
            DataTable result = Search(_table, s);
        }

Ну а искал по такой таблице:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
        static void CreateDataTable()
        {
            _table = new DataTable("table");
            _table.Columns.Add("Id", Type.GetType("System.Int32"));
            _table.Columns.Add("LName", Type.GetType("System.String"));
            _table.Columns.Add("FName", Type.GetType("System.String"));
            _table.Columns.Add("MName", Type.GetType("System.String"));
            _table.Columns.Add("Date", Type.GetType("System.DateTime"));
 
            DataRow row = _table.NewRow();
            row["Id"] = "0";
            row["LName"] = "Иванов";
            row["FName"] = "Иван";
            row["MName"] = "Иванович";
            row["Date"] = new DateTime(2017, 3, 4);
            _table.Rows.Add(row);
 
            row = _table.NewRow();
            row["Id"] = "1";
            row["LName"] = "Петров";
            row["FName"] = "Петр";
            row["MName"] = "Петрович";
            row["Date"] = new DateTime(2017, 2, 8);
            _table.Rows.Add(row);
 
            row = _table.NewRow();
            row["Id"] = "2";
            row["LName"] = "Сергеев";
            row["FName"] = "Сергей";
            row["MName"] = "Сергеевич";
            row["Date"] = new DateTime(2017, 1, 10);
            _table.Rows.Add(row);
 
            row = _table.NewRow();
            row["Id"] = "3";
            row["LName"] = "Николаев";
            row["FName"] = "Николай";
            row["MName"] = "Николаевич";
            row["Date"] = new DateTime(2017, 4, 12);
            _table.Rows.Add(row);
        }

Возможно, не самое изящное решение, но, по крайней, мере работает.

Добавлено через 13 минут
Если нужно искать по неполному совпадению, то == в запросе нужно заменить на Contains
1
mas9
1 / 1 / 3
Регистрация: 30.10.2015
Сообщений: 15
15.06.2017, 23:35  [ТС] #10
Интересный код, но, как я понимаю, если я введу Дятлов Иван Олегович, то он мне найдёт Иванова Ивана Ивановича из-за совпадения в ИЛИ.
0
Shogun31337
494 / 478 / 203
Регистрация: 02.11.2016
Сообщений: 1,439
Завершенные тесты: 2
15.06.2017, 23:54 #11
Нет, не найдет.

Добавлено через 1 минуту
Если написать Дятлов Иван Олегович, то он отсеется еще на строке Дятлов. До Ивана даже дело не дойдет!

Добавлено через 1 минуту
А вот если Дятлов Иван Олегович будет в базе и ввести просто "Иван", то найдется Дятлов и Иванов

Добавлено через 3 минуты
Единственная проблема в датах. Т.к. тип DateTime имеет четкую структуру, а пользователь может вводить как 17.04.2017, так и 2017.04.17 и 17 апреля 2017. Т.е. даты фактически будут совпадать, но поиск даст результат только в одном из этих трех случаев.
0
hoolygan
264 / 271 / 74
Регистрация: 21.06.2016
Сообщений: 1,060
16.06.2017, 10:02 #12
А я бы не городил таких выделываний. На самом деле уже давно обдумали, и поняли,что разделение - это далеко не наилучший вариант. Для меня поиск - это прежде всего гугл.
И там давно поняли, что "Иванов Дятел" и "Дятлов Иван" - по сути одно и то же, если искать по словосочетанию "дят" или "иван".
Мое предложение - просто слямзить немного алгоритм поиска у гугла - т.е. поставить обработчкик измнения в TextBox - и при вводе 3-ех любых символов - искать по всем полям во всей базе по принципу "ИЛИ". У нас на проекте мы именно так и пользуемся, т.е. в таблице из порядка 50 млн записей отбираются все, которые содержат в себе 3 введенных символа, и заполняется грид, потом, при добавлении 4-го и последующих - идет поиск уже в таблице клиента (по DataTable). Этого вполне достаточно для отбора 20-40 записей, из которых пользователь выберет нужное ему. Как у гугла.
Но... это мое субъективное мнение, и вполне может быть не применимо в конкретных задачах.
0
mas9
1 / 1 / 3
Регистрация: 30.10.2015
Сообщений: 15
16.06.2017, 10:49  [ТС] #13
Алгоритм ваш интересный, только не очень понял как реализован поиск по ТАКОМУ частичному совпадению.
0
hoolygan
264 / 271 / 74
Регистрация: 21.06.2016
Сообщений: 1,060
16.06.2017, 11:03 #14
mas9, Я использую только 1 строку поиска, а не делаю кучу текстбоксов для каждого вхождения. А потом использую практически такую же реализацию, как уже показали в примере, но на стороне СУБД. Т.е. что-то такого плана (взято из реального проекта)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private void teFilterString_EditValueChanged(object sender, EventArgs e)
        {
if (teFilterString.Text.Length >= 3 && teFilterString.Text.Substring(0, 3) != rememberedString)
            {
                rememberedString = teFilterString.Text.Substring(0, 3);
 
                DataTable request = new DataTable("Table");
                request.Columns.Add("FilterString", typeof(string));
 
                DataRow r = request.NewRow();
                r["FilterString"] = " ((isnull([OKPO], '') like '%" + rememberedString + "%') or ([ContragentId] like '%" + rememberedString +
                                "%') or ([ShortName] like '%" + rememberedString + "%'))";
                request.Rows.Add(r);
 
                //тут посылка сериализованной таблицы request в СУБД и возврат в другую таблицу, которая биндится к гриду, реализация собственно для Вас не нужна эта
 
            }
            if (teFilterString.Text.Length > 3 && teFilterString.Text.Substring(0, 3) == rememberedString)
            {
                gvfContragents.ActiveFilterString = "[Contragents.ContragentId] LIKE '%" + teFilterString.Text + "%' or [Contragents.ShortName] LIKE '%" +
                                        teFilterString.Text + "%' or [OKPO.Filter] LIKE '%" + teFilterString.Text + "%'";
            }
}
Тут же я запоминаю первые 3 символа, чтобы не дергать СУБД, если стер и заново вбил их же.
Решение может не самое оптимальное, но вполне рабочее.
2
mas9
1 / 1 / 3
Регистрация: 30.10.2015
Сообщений: 15
16.06.2017, 11:35  [ТС] #15
Так гораздо понятнее стало) Интересный алгоритм) Я помню на лабораторной заморачивался похожим чтобы высчитать процент совпадения строк. Т.е. abc совпадает с abc на 100%, но и abc с bca тоже имеет совпадение)
0
Shogun31337
494 / 478 / 203
Регистрация: 02.11.2016
Сообщений: 1,439
Завершенные тесты: 2
16.06.2017, 12:59 #16
hoolygan, действительно, интересный алгоритм. Как то раньше не интересовался какой алгоритм поиска использует гугл, хотя только им и пользуюсь. Спасибо за мысль! Возьму на вооружение!
0
hoolygan
264 / 271 / 74
Регистрация: 21.06.2016
Сообщений: 1,060
16.06.2017, 13:37 #17
Shogun31337, - у гугла алгоритм думаю на несколько порядков запутанней - это чисто поведение поиска в гугле, и мое субъективное представление оного
0
Shogun31337
494 / 478 / 203
Регистрация: 02.11.2016
Сообщений: 1,439
Завершенные тесты: 2
16.06.2017, 15:05 #18
Цитата Сообщение от hoolygan Посмотреть сообщение
у гугла алгоритм думаю на несколько порядков запутанней
Ну это то понятно. Я имел в виду общую концепцию выборки из БД по трем символам и дальнейшей фильтрации в DataSet'е.
Цитата Сообщение от hoolygan Посмотреть сообщение
это чисто поведение поиска в гугле, и мое субъективное представление оного
Аааа! Ясно! Ну все равно идея интересная! Поэксперементирую с ней на досуге.
0
16.06.2017, 15:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.06.2017, 15:05
Привет! Вот еще темы с решениями:

Поиск в базе данных по нескольким параметрам
Здравствуйте, подскажите кто-нибудь, как сделать следующее: В попупе находятся...

Необходимо осуществить поиск по параметрам и вывести в таблицу StringGrid список людей по этим параметрам
procedure TForm1.Button1Click(Sender: TObject); // Поиск по параметрам var i:...

Поиск данных по параметрам, которые могут быть не заполнены
Привет, ребята. У меня есть такая функция: public static List&lt;string&gt;...

Поиск ячейки по двум параметрам и запись в нее данных
Ребята, прошу помощи! Наверняка уже есть решение по моей задачке. Бросьте...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru