Форум программистов, компьютерный форум, киберфорум
C#: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.57/21: Рейтинг темы: голосов - 21, средняя оценка - 4.57
18 / 13 / 5
Регистрация: 08.01.2016
Сообщений: 315

Как составить запрос на выборку

15.09.2021, 09:52. Показов 4524. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день! Подскажите, пожалуйста, как можно решить следующий вопрос:
Имеется БД с таблицей:
id - name - surname - age - dateIn - estimation - regNumber

У меня есть код для выборки в БД MySQL:
C#
1
2
3
4
5
                System.Data.DataTable datatable = new DataTable();
                MySqlDataAdapter adapter = new MySqlDataAdapter();
                MySqlCommand command = new MySqlCommand("SELECT * FROM `student` WHERE `name` = @uName AND `surname` = @uSurname", db.getConnection());
                command.Parameters.Add("@uName ", MySqlDbType.VarChar).Value = name ;              
                command.Parameters.Add("@uSurname", MySqlDbType.UInt32).Value = surname;
Здесь я делаю выборку по имени и фамилии студента... А как написать код, если я заранее не знаю какую выборку будет использовать пользователь... Допустим, он может решить искать студента по имени и возрасту... Мне придется под это условие заранее предусмотреть новый запрос? Типо этого?

C#
1
2
3
4
5
                System.Data.DataTable datatable = new DataTable();
                MySqlDataAdapter adapter = new MySqlDataAdapter();
                MySqlCommand command = new MySqlCommand("SELECT * FROM `student` WHERE `name` = @uName AND `age` = @uAge", db.getConnection());
                command.Parameters.Add("@uName ", MySqlDbType.VarChar).Value = name ;              
                command.Parameters.Add("@uAge", MySqlDbType.UInt32).Value = age;
А если я предлагаю пользователю много вариантов поиска, мне нужно под каждый из вариантов новый запрос предусмотреть?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.09.2021, 09:52
Ответы с готовыми решениями:

Как составить запрос SELECT на выборку из связанных таблиц
Всем привет. Вопрос простой, но вот уже три дня сижу пробую ничего не получается. Есть две связанные таблички в базе на ms access, есть...

Составить запрос на выборку
Есть у меня в программе 2 listbox. 1 - Список читателей, 2 должен вывести книг которых взял читатель , который мы выбрали в listbox1. ...

БД и sql - составить запрос на выборку данных из базы
добрый день. создаю приложение на c# и sql server 2005 и возникла одна небольшая проблема. Помогите пожалуйста составить запрос на выборку...

25
2810 / 1679 / 885
Регистрация: 14.04.2015
Сообщений: 5,723
15.09.2021, 10:32
Elkatib, попробуйте так
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
42
            string Query = "SELECT * FROM `student` WHERE 1 = 1 ";
 
            if (textBox1.Text.Length != 0)
            {
                Query += $"and `name` = @uName ";
            }
            if (textBox2.Text.Length != 0)
            {
                Query += $"and `surname` = @uSurname ";
            }
            if (textBox3.Text.Length != 0)
            {
                Query += $"and `age` = @uAge ";
            }            
            Query += $"and `dateIn` = @uDateIn";
 
            if (textBox4.Text.Length != 0)
            {
                Query += $"and `estimation` = @uEstimation ";
            }
            if (textBox5.Text.Length != 0)
            {
                Query += $"and `regNumber` = @uRegNumber ";
            }
 
            System.Data.DataTable datatable = new DataTable();
 
            MySqlDataAdapter adapter = new MySqlDataAdapter();
 
            MySqlCommand command = new MySqlCommand(Query, db.getConnection());
 
            command.Parameters.Add("@uName", MySqlDbType.VarChar).Value = textBox1.Text;
 
            command.Parameters.Add("@uSurname", MySqlDbType.VarChar).Value = textBox2.Text;
 
            command.Parameters.Add("@uAge", MySqlDbType.UInt32).Value = Convert.ToInt32(textBox3.Text);
 
            command.Parameters.Add("@uDateIn", MySqlDbType.Date).Value = Convert.ToDateTime(dateTimePicker1.Text).ToString("yyyy-MM-dd");
 
            command.Parameters.Add("@uEstimation", MySqlDbType.UInt32).Value = Convert.ToInt32(textBox4.Text);
 
            command.Parameters.Add("@uRegNumber", MySqlDbType.VarChar).Value = textBox5.Text;
0
Эксперт .NET
 Аватар для Usaga
14307 / 9388 / 1355
Регистрация: 21.01.2016
Сообщений: 35,405
15.09.2021, 10:58
Цитата Сообщение от AndreyVorobey Посмотреть сообщение
WHERE 1 = 1 ";
Да блин... Когда же переведутся люди, что так делают?))
0
2810 / 1679 / 885
Регистрация: 14.04.2015
Сообщений: 5,723
15.09.2021, 11:17
Usaga, это был самый простой способ, как по мне, чтоб объединить WHERE и то, что после)
0
4217 / 3059 / 583
Регистрация: 21.01.2011
Сообщений: 13,203
15.09.2021, 11:20
Цитата Сообщение от Usaga Посмотреть сообщение
Когда же переведутся люди, что так делают?
При создании запроса иногда приходится комментировать строки. При наличии в первой строке 1 = 1 любая строка комментируется одинаково просто. Если первая строка "значащая", то ее комментировать сложнее (например, надо кроме этой строки комментировать AND во второй). Не могу сказать, что я постоянно пользую 1 = 1, но иногда бывает.
0
Эксперт .NET
 Аватар для Usaga
14307 / 9388 / 1355
Регистрация: 21.01.2016
Сообщений: 35,405
15.09.2021, 11:38
AndreyVorobey, Grossmeister, да не нужно так делать вообще.

У вас уже идёт набивание условий фильтрации:

C#
1
2
3
4
5
6
7
8
            if (textBox1.Text.Length != 0)
            {
                Query += $"and `name` = @uName ";
            }
            if (textBox2.Text.Length != 0)
            {
                Query += $"and `surname` = @uSurname ";
            }
Вместо конкатенации можно (и нужно) набивать List<string> этими строками. Потом можно сделать тупо String.Join(" AND ", predicateStrings) и всё. Не надо никаких 1 = 1.

При этом, если такая коллекция пустой получилась, то и WHERE добавлять не надо. Всё очень просто можно сделать и красиво.
0
4217 / 3059 / 583
Регистрация: 21.01.2011
Сообщений: 13,203
15.09.2021, 12:23
Цитата Сообщение от Usaga Посмотреть сообщение
да не нужно так делать вообще
Лично я все запросы (ну разве что кроме самых простых) сначала отлаживаю так (например, в PL/SQL Developer) и только потом переношу в клиентскую программу. Если в запросе появилось 1 = 1, то так и копирую без правки. Только константы заменяю на переменные.
0
Эксперт .NET
 Аватар для Usaga
14307 / 9388 / 1355
Регистрация: 21.01.2016
Сообщений: 35,405
15.09.2021, 12:34
Grossmeister, я тоже большие запросы отлаживаю в живую. Но у меня уже более пяти лет не появляется 1 = 1. Я просто в упор не понимаю, как можно это добавлять в запрос имея на руках язык общего назначения или вообще ORM.
0
2810 / 1679 / 885
Регистрация: 14.04.2015
Сообщений: 5,723
15.09.2021, 13:12
Usaga, исправляюсь)
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
42
43
            string Query = "SELECT * FROM `student` ";
 
            List<string> queryParams = new List<string>();
 
            if (textBox1.Text.Length != 0)
            {
                queryParams.Add("`name` = @uName ");
            }
            if (textBox2.Text.Length != 0)
            {
                queryParams.Add("`surname` = @uSurname ");
            }
            if (textBox3.Text.Length != 0)
            {
                queryParams.Add("`age` = @uAge ");
            }
            queryParams.Add("`dateIn` = @uDateIn");
 
            if (textBox4.Text.Length != 0)
            {
                queryParams.Add("`estimation` = @uEstimation ");
            }
            if (textBox5.Text.Length != 0)
            {
                queryParams.Add("`regNumber` = @uRegNumber ");
            }
            System.Data.DataTable datatable = new DataTable();
 
            MySqlDataAdapter adapter = new MySqlDataAdapter();
 
            MySqlCommand command = new MySqlCommand(Query + (queryParams.Count != 0 ? "Where" + String.Join("and ", queryParams) : ""), db.getConnection());
 
            command.Parameters.Add("@uName", MySqlDbType.VarChar).Value = textBox1.Text;
 
            command.Parameters.Add("@uSurname", MySqlDbType.VarChar).Value = textBox2.Text;
 
            command.Parameters.Add("@uAge", MySqlDbType.UInt32).Value = Convert.ToInt32(textBox3.Text);
 
            command.Parameters.Add("@uDateIn", MySqlDbType.Date).Value = Convert.ToDateTime(dateTimePicker1.Text).ToString("yyyy-MM-dd");
 
            command.Parameters.Add("@uEstimation", MySqlDbType.UInt32).Value = Convert.ToInt32(textBox4.Text);
 
            command.Parameters.Add("@uRegNumber", MySqlDbType.VarChar).Value = textBox5.Text;
0
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
15.09.2021, 18:21
Цитата Сообщение от AndreyVorobey Посмотреть сообщение
command.Parameters.Add("@uDateIn", MySqlDbType.Date).Value = Convert.ToDateTime(dateTimePicker1.Text) .ToString("yyyy-MM-dd");
Это просто жесть.
Берем из контрола, специально предназначенного для ввода даты, не дату, а ее текстовое отображение.
Преобразуем его в дату.
Преобразуем дату в строку.
Отправляем строку в БД, где она будет преобразована в дату. Вместо
C#
1
command.Parameters.Add("@uDateIn", MySqlDbType.Date).Value =dateTimePicker1.Value;
0
Эксперт .NET
 Аватар для Usaga
14307 / 9388 / 1355
Регистрация: 21.01.2016
Сообщений: 35,405
15.09.2021, 19:38
Igr_ok, зато без 1 = 1) Уже прогресс)
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
15.09.2021, 20:57
Цитата Сообщение от Igr_ok Посмотреть сообщение
Это просто жесть.

Не по теме:

Igr_ok, работает? - не трогай.

0
2810 / 1679 / 885
Регистрация: 14.04.2015
Сообщений: 5,723
15.09.2021, 22:10
Igr_ok, я лупил, чтоб наверняка, потому что не было возможности протестить, но спасибо за отзыв)
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
16.09.2021, 01:14
Цитата Сообщение от AndreyVorobey Посмотреть сообщение
я лупил, чтоб наверняка
Это называется "грязный код", когда то, что пишется в 20 символов, записывается в 200.

Добавлено через 3 минуты
А вот необходимой проверки введенных данных (валидации) в Вашем зубодробительном коде и нетути.
Чему же Вы учите молодежь ?
0
2810 / 1679 / 885
Регистрация: 14.04.2015
Сообщений: 5,723
16.09.2021, 09:24
Igr_ok, пожалуйста, исправляюсь)
C#
1
command.Parameters.Add("@uDateIn", MySqlDbType.Date).Value = dateTimePicker1.Value.ToShortDateString();
MsGuns, ой, с валидацией уже пусть как-то сами позанимаются
Цитата Сообщение от MsGuns Посмотреть сообщение
зубодробительном коде
кстати, жду Ваш "элегантный" способ построителя запросов)
0
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
16.09.2021, 10:47
Цитата Сообщение от AndreyVorobey Посмотреть сообщение
пожалуйста, исправляюсь)
Цитата Сообщение от AndreyVorobey Посмотреть сообщение
dateTimePicker1.Value.ToShortDateString()
Нет, вы неисправимы)
0
2810 / 1679 / 885
Регистрация: 14.04.2015
Сообщений: 5,723
16.09.2021, 10:50
Igr_ok, точно?
потому что dateTimePicker1.Value возвращает дату и время
0
Эксперт .NET
 Аватар для Usaga
14307 / 9388 / 1355
Регистрация: 21.01.2016
Сообщений: 35,405
16.09.2021, 11:22
AndreyVorobey, но зачем эту дату в строку перегонять, когда сам объект даты надо передать?)
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
16.09.2021, 14:18
AndreyVorobey,
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
        public List<AnimalGrid> Fetch_AnimalGrid(GridContainer cnt)
        { 
            // Извлекает животных с использованием глобальных фильтров (класс, континент, страна, город) 
            // и локального фильтра (образец), заданного по текущей отсортированной колонке,
            // затем сортирует записи по указанной колонки сортировки по возрастанию или убыванию
            // По данным, полученным из контейнера cnt формирует динамический запрос и отсылает 
            // его на SQL-сервер. Полученные данные заворачивает в класс List<AnimalGrid>, 
            // указатель на который возвращает.
            // Если выбранных записей нет, то возвращается пустой список
            List<AnimalGrid> res = new List<AnimalGrid>();
            SQLWhere = "";
            // Глобальные фильтры
            if (cnt.TreeNodeId > 0) ModifySQLWhere("CHARINDEX('[" 
                + cnt.TreeNodeId.ToString() + "]', dbo.UsF_GetFullTreePath(TN.TN_PID)) > 0");
            if (cnt.CityId > 0) ModifySQLWhere("CI.CIT_ID = " + cnt.CityId.ToString());
            else if (cnt.CountryId > 0) ModifySQLWhere("CT.CNT_ID = " + cnt.CountryId.ToString());
            else if (cnt.ContinentId > 0) ModifySQLWhere("CN.CONT_ID = " + cnt.ContinentId.ToString());
            // Дополнительный фильтр (элемент разметки "Фильтр")
            if (!String.IsNullOrEmpty(cnt.FilterValue)) ModifySQLWhere(cnt.OrderColumnName + " like '%" + cnt.FilterValue + "%'");
            // Сортировка
            SQLOrderBy = " ORDER BY " + cnt.OrderColumnName;
            if (cnt.OrderType.ToLower() == "desc") SQLOrderBy += " DESC ";
            // Итоговый текст запроса
            SQL = "SELECT TN.TN_ID, dbo.UsF_GetFullTreePath(TN.TN_PID) AS TN_Tree, TN.TN_Name, "
                + "CI.CIT_ID, CI.CIT_Name, CT.CNT_ID, CT.CNT_Name, CN.CONT_ID, CN.CONT_Name, "
                + "TN.TN_Owner, TN.TN_Gender, TN.TN_Age FROM TREENAMES TN "
                + " LEFT JOIN DIR_CITY CI ON CI.CIT_ID = TN.TN_CID "
                + " LEFT JOIN DIR_COUNTRY CT ON CT.CNT_ID = CI.CIT_PID "
                + " LEFT JOIN DIR_CONTINENT CN ON CN.CONT_ID = CT.CNT_PID "
                + SQLWhere + SQLOrderBy;
            using (SqlConnection con = new SqlConnection(CONNECTION_STRING))
            {
                con.Open();
                SqlCommand comm = new SqlCommand(SQL, con);
                SqlDataReader reader = comm.ExecuteReader();
                if (reader.HasRows)
                    while (reader.Read())
                    {
                        res.Add(new AnimalGrid 
                        {
                            TN_ID = reader[0] == DBNull.Value? 0 : (int) reader[0],
                            TN_Tree = reader[1] as string ?? "",
                            TN_Name = reader[2] as string ?? "",
                            CIT_ID = reader[3] == DBNull.Value? 0 : (int) reader[3],
                            CIT_Name = reader[4] as string ?? "",
                            CNT_ID = reader[5] == DBNull.Value ? 0 : (int)reader[5],
                            CNT_Name = reader[6] as string ?? "",
                            CONT_ID = reader[7] == DBNull.Value ? 0 : (int)reader[7],
                            CONT_Name = reader[8] as string ?? "",
                            TN_Owner = reader[9] as string ?? "",
                            TN_Gender = reader[10] == DBNull.Value ? 0 : (int)reader[10],
                            TN_Age = reader[11] == DBNull.Value ? 0 : (int)reader[11],
                        });
                    }
                reader.Close();
                comm.Dispose();
            }
            return res;
        }
Добавлено через 1 минуту
C#
1
2
3
4
5
6
7
        private void ModifySQLWhere(string WhereAtom)
        {
            // Формирует строку с предикатом WHERE если первой условие 
            // или дозаписывает новое условие, если строка уже имеет контекст
            if (SQLWhere == "") SQLWhere = " WHERE " + WhereAtom;
            else SQLWhere += " AND " + WhereAtom;
        }
Добавлено через 2 минуты
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
    public class GridContainer
    {
        // Статус пользователя
        public USERPROFILE UserProfile; // null если гость
 
        // Глобальные фильтры
        public int TreeNodeId { get; set; }  // Id активного узла дерева классов (0 -если нет)
        public int ContinentId { get; set; }  // Id текущего континента (0 - если нет)
        public int CountryId { get; set; }  // Id текущей страны в континенте (0 - если нет)
        public int CityId { get; set; }  // Id текущего города в стране (0 - если нет)
 
        // Локальный фильтр
        public string FilterValue { get; set; }  // Образец фильтра ("" - если нет)
 
        // Параметры сортировки
        public string OrderColumnName { get; set; }  // Имя поля набора данных
        public string OrderHeaderText { get; set; }  // Имя колонки в сетке (текст шапки)
        public string OrderType { get; set; }  // Порядок сортировки (DESC-убывание, иначе-возрастание)
 
        // Состояние сетки
        public int AnimalId { get; set; }  // Id активной строки сетки (0 -если нет)
 
        // Списки 
        public List<ComboBoxList> ListContinents;  
        public List<ComboBoxList> ListCountries; // пустой если не указан континент
        public List<ComboBoxList> ListCities;   // пустой если не указана страна
        public List<ComboBoxList> ListRootTreeNodes;
    }
0
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
16.09.2021, 17:55
Цитата Сообщение от MsGuns Посмотреть сообщение
CONT_ID = reader[7] == DBNull.Value ? 0 : (int)reader[7],
Еще и память развивает. Это ж надо помнить, в каком порядке поля в запросе возвращаются)
Я обычно пихаю reader в DataTable, а потом перебираю все свойства в классе в алфавитном порядке, чтобы ничего не пропустить, копируя название свойства в название поля
C#
1
animalGrid.CONT_ID = Utils.GetIntValue(row["CONT_ID"]);
Если нужно задать фильтр по нескольким условиям, некоторые из которых могут быть не указаны, то использую условие для параметра
C#
1
"SELECT * FROM `student`where (@Field1 is null or Field1=@Field1) or (@Field2 is null or Field2=@Field2) or..."
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.09.2021, 17:55
Помогаю со студенческими работами здесь

Как правильно составить запрос на выборку
Здравствуйте, буду благодарен, если подскажете как сделать интересующую меня выборку в БД. В таблице есть поле категория, в которое...

Составить запрос на выборку
В общем есть таблица с новостями. Мне нужно выбрать новости дата у которых меньше текущей с лимитом в 20, И новости у которых дата больше...

Составить sql запрос на выборку
Есть таблица с такими столбиками sale_id, sale_kod, sale_name, sale_prise, sale_date, sale_point Мне нужно из них сформировать запрос...

Составить запрос к БД на выборку фильмов
есть таблица в БД &quot;kino&quot; 2 поля: название фильма &quot;title&quot; и актер играющий роль &quot;actor&quot; нужно выбрать все фильмы где играют роль...

Помогите составить запрос на выборку
Здравствуйте. Ребята,помогите пожалуйста. Есть пять таблиц: CREATE TABLE Customer ( CustNo INTEGER, FirstName VARCHAR2(20), ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru