Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
 Аватар для Vyazan
12 / 12 / 2
Регистрация: 19.03.2012
Сообщений: 175
MS Access

Проблема длинного запроса SELECT в Access

08.08.2017, 17:34. Показов 2470. Ответов 21

Студворк — интернет-сервис помощи студентам
Всем привет!
В процессе выполнения цикла в Delphi формируется запрос:
Delphi
1
2
3
if f = true then
                q:=q+' or (НомерСчета = '+''''+schet+''' and ДатаСчета = CDate('''+data+'''))' else
                q:='(НомерСчета = '+''''+schet+''' and ДатаСчета = CDate('''+data+'''))';
, который получается очень длинный. Акцесс ругается на слишком сложный запрос. Как его можно укоротить?
Запросы идут через Fdquery (ADOQuery).
Кому интересно под спойлером весь запрос:
Кликните здесь для просмотра всего текста
select * from Счета where (НомерСчета = '00000000374' and ДатаСчета = CDate('20.12.2012 12:00:00')) or (НомерСчета = '00000000005' and ДатаСчета = CDate('15.01.2013 12:00:01')) or (НомерСчета = '00000000009' and ДатаСчета = CDate('15.01.2013 12:00:05')) or (НомерСчета = '00000000016' and ДатаСчета = CDate('23.01.2013 14:48:04')) or (НомерСчета = '00000000026' and ДатаСчета = CDate('04.02.2013 13:38:26')) or (НомерСчета = '00000000034' and ДатаСчета = CDate('12.02.2013 12:31:54')) or (НомерСчета = '00000000035' and ДатаСчета = CDate('12.02.2013 12:52:48')) or (НомерСчета = '00000000046' and ДатаСчета = CDate('19.02.2013 12:39:41')) or (НомерСчета = '00000000054' and ДатаСчета = CDate('25.02.2013 10:40:00')) or (НомерСчета = '00000000058' and ДатаСчета = CDate('27.02.2013 12:36:48')) or (НомерСчета = '00000000061' and ДатаСчета = CDate('01.03.2013 16:25:14')) or (НомерСчета = '00000000059' and ДатаСчета = CDate('04.03.2013 12:00:00')) or (НомерСчета = '00000000069' and ДатаСчета = CDate('13.03.2013 11:35:14')) or (НомерСчета = '00000000073' and ДатаСчета = CDate('15.03.2013 14:44:38')) or (НомерСчета = '00000000075' and ДатаСчета = CDate('15.03.2013 15:00:22')) or (НомерСчета = '00000000077' and ДатаСчета = CDate('18.03.2013 12:36:53')) or (НомерСчета = '00000000080' and ДатаСчета = CDate('19.03.2013 11:06:05')) or (НомерСчета = '00000000083' and ДатаСчета = CDate('19.03.2013 12:49:42')) or (НомерСчета = '00000000089' and ДатаСчета = CDate('20.03.2013 13:49:17')) or (НомерСчета = '00000000091' and ДатаСчета = CDate('21.03.2013 12:45:47')) or (НомерСчета = '00000000094' and ДатаСчета = CDate('22.03.2013 10:41:53')) or (НомерСчета = '00000000106' and ДатаСчета = CDate('02.04.2013 13:09:30')) or (НомерСчета = '00000000112' and ДатаСчета = CDate('04.04.2013 12:30:23'))
и далее в таком же духе
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.08.2017, 17:34
Ответы с готовыми решениями:

Вставка id из запроса select в другой запрос insert
Доброго времени суток! есть firebird+delphi xe, задача следующая: Вывожу через select в ComboBox items значения из таблицы STREET...

Как проанализировать результат запроса SELECT в TQuery.ExecSQL?
Требуется,не отображая на экране, проверить число записей в результирующем наборе данных, и если > 0, то вернуть значение поля 'name'. ...

Кто может рассказать про способ запроса к таблице access с excel через select from inner join
Имеется база, и надо через excel при помощи vba импортировать запрос. приоритет в шапке (select from inner join). Благодарен любой помощи.

21
Native x86
Эксперт Hardware
 Аватар для quwy
6857 / 3790 / 1025
Регистрация: 13.02.2013
Сообщений: 11,861
08.08.2017, 18:13
Лучший ответ Сообщение было отмечено Vyazan как решение

Решение

Ничего вы не сделаете, если СУБД не может переварить запрос.

Делайте SELECT * FROM TABLE без WHERE и отбирайте нужные записи либо в цикле прохода по датасету (если выборка делается для обработки данных программой) или в обработчике OnFilterRecord (если их нужно отобразить в виде грида на форме).
1
 Аватар для Vyazan
12 / 12 / 2
Регистрация: 19.03.2012
Сообщений: 175
08.08.2017, 18:31  [ТС]
Цитата Сообщение от quwy Посмотреть сообщение
Ничего вы не сделаете, если СУБД не может переварить запрос.
Жаль. Буду пробовать делать, как Вы советуете.
0
5967 / 4543 / 1094
Регистрация: 29.08.2013
Сообщений: 28,157
Записей в блоге: 3
08.08.2017, 19:05
а если сделать
SQL
1
2
3
4
SELECT * FROM Счета WHERE (НомерСчета = '00000000374' AND ДатаСчета = CDate('20.12.2012 12:00:00'))
UNION
SELECT * FROM Счета WHERE (НомерСчета = '00000000374' AND ДатаСчета = CDate('20.12.2012 12:00:00'))
..
хотя конечно нужно запрос оптимизировать
1
Native x86
Эксперт Hardware
 Аватар для quwy
6857 / 3790 / 1025
Регистрация: 13.02.2013
Сообщений: 11,861
08.08.2017, 19:07
qwertehok, обычно имеет место тупое ограничение длины запроса (например размером 65535 символов), поэтому такой вариант еще менее вероятен.
1
08.08.2017, 19:52

Не по теме:

в аксессе не пробовал, но в MSSQL у меня был длиииииииииииииииииииииииииииинный запрос
и все работало

1
09.08.2017, 01:59

Не по теме:

Цитата Сообщение от qwertehok Посмотреть сообщение

Не по теме:

в аксессе не пробовал, но в MSSQL у меня был длиииииииииииииииииииииииииииинный запрос
и все работало

В нормальных базах там стоит очень большой лимит.

1
пофигист широкого профиля
4769 / 3204 / 862
Регистрация: 15.07.2013
Сообщений: 18,609
09.08.2017, 02:00
Цитата Сообщение от Vyazan Посмотреть сообщение
Кому интересно под спойлером весь запрос:
Ох как тут не хватаете "архитектора проекта", который бы сказал что такой запрос - просто бред сивой кобылы в темную мартовскую ночь!
Тут явно надо менять именно архитектуру.
1
Айлурофил
 Аватар для Massaraksh7
511 / 445 / 111
Регистрация: 27.05.2017
Сообщений: 2,677
Записей в блоге: 5
09.08.2017, 03:12
Цитата Сообщение от northener Посмотреть сообщение
Ох как тут не хватаете "архитектора проекта", который бы сказал что такой запрос - просто бред сивой кобылы в темную мартовскую ночь!
Тут явно надо менять именно архитектуру.
Не соглашусь. Как ни меняй архитектуру, а проблема представления выборочных данных по БД никуда не денется. В общем случае.
0.50
 Аватар для krapotkin
6849 / 4676 / 1464
Регистрация: 14.04.2014
Сообщений: 20,664
Записей в блоге: 21
09.08.2017, 07:06
в данном конкретном случае нужно формировать временную таблицу
в аксессе их видимо нет в явном виде, поэтому делаете таблицу
UID, INV_NUM, INV_DATE
первую колонку заполняете например GUID во вторую и третью пишите свои номера и даты
потом делаете JOIN c этой таблицей, выбирая данные по вашему GUID
после работы с таблицей удалите эти данные
2
Айлурофил
 Аватар для Massaraksh7
511 / 445 / 111
Регистрация: 27.05.2017
Сообщений: 2,677
Записей в блоге: 5
09.08.2017, 11:25
Или сразу выбирать данные в память Sql-запросами в цикле по одной накладной.
1
 Аватар для Vyazan
12 / 12 / 2
Регистрация: 19.03.2012
Сообщений: 175
09.08.2017, 13:52  [ТС]
Цитата Сообщение от krapotkin Посмотреть сообщение
в данном конкретном случае нужно формировать временную таблицу
в аксессе их видимо нет в явном виде, поэтому делаете таблицу
UID, INV_NUM, INV_DATE
первую колонку заполняете например GUID во вторую и третью пишите свои номера и даты
потом делаете JOIN c этой таблицей, выбирая данные по вашему GUID
после работы с таблицей удалите эти данные
Там куча данных, которые еще нужно отобразить пользователю и он по ним осуществляет навигацию. Их заносить тоже во временную БД - слишком геморойно, как мне кажется. Или я что-то недопонимаю в Вашем варианте решения.

Цитата Сообщение от Massaraksh7 Посмотреть сообщение
Или сразу выбирать данные в память Sql-запросами в цикле по одной накладной.
Данные в память я выберу, а как после их поместить в dataset, дабы пользователь сие дело мог просмотреть.

Проясню немного ситуацию. Может кто предложит другой вариант решения:
Программа работает в связке 1C + Delphi + Access . В дальнейшем БД Access будет переноситься в сеть на MySQL. 1С - базовая версия, поэтому нужных вещей не запилишь. В Access хранятся все номера счетов из 1С, а вот товары из счетов, подгружаются, только, когда пользователь хочет их просмотреть. Это сделано для того, что бы сразу не получать на овер-дофига счетов, огромное количество товаров, что непременно займет очень много времени.
Сейчас реализуется поиск. Так как товары в акцессе есть не по всем счетам + могли 5 минут назад могли быть изменены в 1С, то логичнее их искать именно в 1С. Пользователь вводит в строку поиска фразу, программа пробегается по всем счетам и их товарам. Если искомое слово присутствует в наименовании товара, то запоминает номер и дату счета (два параметра, т.к. номер уникален в течение года). Соответственно, если фразу часто используемая, то и номеров счета будет много, что приводит к очень длинному запросу. И запросом уже выводятся все счета, в товарах которых найдена поисковая фраза.
Миниатюры
Проблема длинного запроса SELECT в Access  
0
5967 / 4543 / 1094
Регистрация: 29.08.2013
Сообщений: 28,157
Записей в блоге: 3
09.08.2017, 15:09
Цитата Сообщение от Vyazan Посмотреть сообщение
Пользователь вводит в строку поиска фразу, программа пробегается по всем счетам и их товарам
а таблицы с номенклатурой у вас нет?
искать товары нужно в таблице номенклатуры что бы получить ID товара, далее этот ID мы ищем в документах (причем ID должен быть проиндексирован) так мы получим номер документа

PS
зачем вам тут Аксесс?
зачем вам тут делфи?
все отлично хранится и ищется прямо в 1с (а если перенести ее еще и на MSSQL)
1
 Аватар для krapotkin
6849 / 4676 / 1464
Регистрация: 14.04.2014
Сообщений: 20,664
Записей в блоге: 21
09.08.2017, 15:21
Цитата Сообщение от Vyazan Посмотреть сообщение
временную БД
Цитата Сообщение от krapotkin Посмотреть сообщение
временную таблицу
это сильно не одно и то же

Цитата Сообщение от Vyazan Посмотреть сообщение
Там куча данных
ничего не знаю про кучу данных, но я вижу запрос, который вы привели в #1
это в чистом виде
Delphi
1
2
3
select * from Счета s
inner join tmp_table tmp on (s.НомерСчета = tmp.INV_NUM and s.ДатаСчета = tmp.INV_DATE)
where tmp.UID='xxxxxxxxx'
согласитесь, слегка покороче
а данные на выходе те же
1
 Аватар для Vyazan
12 / 12 / 2
Регистрация: 19.03.2012
Сообщений: 175
09.08.2017, 16:48  [ТС]
Цитата Сообщение от qwertehok Посмотреть сообщение
а таблицы с номенклатурой у вас нет?
искать товары нужно в таблице номенклатуры что бы получить ID товара, далее этот ID мы ищем в документах (причем ID должен быть проиндексирован) так мы получим номер документа
Хорошо, нашел я Вашим методом все номера счетов с датами. Дальше у меня такой же длинный запрос получится, что бы отобразить эти счета из Access.
Цитата Сообщение от qwertehok Посмотреть сообщение
зачем вам тут Аксесс?
зачем вам тут делфи?
В Access будут храниться данные о статусе счета, о комплектации товара компонентами, которые никак не фигурируют в 1С и пр. Делфи все это дело связывает.
Цитата Сообщение от qwertehok Посмотреть сообщение
все отлично хранится и ищется прямо в 1с
Цитата Сообщение от Vyazan Посмотреть сообщение
1С - базовая версия, поэтому нужных вещей не запилишь.
Добавлено через 9 минут
Цитата Сообщение от krapotkin Посмотреть сообщение
Delphi
1
2
3
select * from Счета s
inner join tmp_table tmp on (s.НомерСчета = tmp.INV_NUM and s.ДатаСчета = tmp.INV_DATE)
where tmp.UID='xxxxxxxxx'
согласитесь, слегка покороче
а данные на выходе те же
Я не силен в SQL. Можно, если не сложно, пояснить что есть что и зачем оно в Вашем запросе?
0
5967 / 4543 / 1094
Регистрация: 29.08.2013
Сообщений: 28,157
Записей в блоге: 3
09.08.2017, 17:03
Цитата Сообщение от Vyazan Посмотреть сообщение
1С - базовая версия, поэтому нужных вещей не запилишь.
какая нафиг базовая?
1с это конструктор - там язык программирования. 1с это вообще - аксесс + делфи (и формы есть и код писать можно)

Цитата Сообщение от Vyazan Посмотреть сообщение
Хорошо, нашел я Вашим методом все номера счетов с датами.
"у меня" номера документов, они проиндексированы, значит поиск идет быстрее
а дальше тебе отобразить нужные документы можно использовав всего 1 select и никаких запросов на 100500 строк не надо

Цитата Сообщение от Vyazan Посмотреть сообщение
В Access будут храниться данные о статусе счета, о комплектации товара компонентами, которые никак не фигурируют в 1С и пр.
да почему аксесс то? он как база отстой и как приложение для разработки отстой
почему не взять нормальную базу?

ЗЫ развели зоопарк
ну не умеешь на 1с писать - ладно
ну знаешь SQL - ладно
но городить огород то зачем? почему бы не спросить у тех кто знает?

подскажи какого размера база в аксесе и сколько по времени идет поиск?
1
 Аватар для krapotkin
6849 / 4676 / 1464
Регистрация: 14.04.2014
Сообщений: 20,664
Записей в блоге: 21
09.08.2017, 17:04
простой перевод вполне канает

выбрать все поля из таблы Счета, которые имеются еще и в таблице tmp_table
если номерСчета=INV_NUM и ДатаСчета=INV_DATE

это называется пересечение множеств
http://www.skillz.ru/dev/php/a... OUTER.html

работать с БД без знания SQL вам все равно не удастся
1
 Аватар для Vyazan
12 / 12 / 2
Регистрация: 19.03.2012
Сообщений: 175
10.08.2017, 16:20  [ТС]
Цитата Сообщение от qwertehok Посмотреть сообщение
какая нафиг базовая?
Базовая - это значит она не позволяет настраивать конфигурацию.
Цитата Сообщение от qwertehok Посмотреть сообщение
"у меня" номера документов, они проиндексированы, значит поиск идет быстрее
а дальше тебе отобразить нужные документы можно использовав всего 1 select и никаких запросов на 100500 строк не надо
Вы про поиск в 1С или Access? Если Access, то, пожалуйста, поясните подробнее, как Вы предлагаете реализовать поиск.
Цитата Сообщение от qwertehok Посмотреть сообщение
почему не взять нормальную базу?
Потому что к access я привык, меня он вполне устраивает, если не считать данной ситуации.
Цитата Сообщение от qwertehok Посмотреть сообщение
почему бы не спросить у тех кто знает?
Этим я сейчас и занимаюсь.
Цитата Сообщение от qwertehok Посмотреть сообщение
подскажи какого размера база в аксесе и сколько по времени идет поиск?
БД не большая по размеру. Тот поиск, который в первом посте (с формированием длинного запроса) сейчас занимает около 5 секунд.

Добавлено через 28 минут
Цитата Сообщение от krapotkin Посмотреть сообщение
это называется пересечение множеств
http://www.skillz.ru/dev/php/a... OUTER.html
Большое спасибо за ссылку. Буду осознавать смысл написанного там.
Я так понимаю логика такая: создаем временную таблицу, ищем необходимую информацию, при нахождении записываем в временную таблицу нужные нам данные, после делаем выборку с объединением JOIN и удаляем таблицу?
0
W
 Аватар для kavasaka
115 / 115 / 33
Регистрация: 16.04.2013
Сообщений: 750
10.08.2017, 16:46
Лучший ответ Сообщение было отмечено Vyazan как решение

Решение

В таблицу я бы писал только 1 поле id из таблицы Счета. И только те id которые удовлетворяют всем этим длинючим условиям из where. А потом JOIN этой таблицы с Счетами - отсеет из Счетов все прочие строки. т.е. получаем то же что мог бы сделать запрос если бы работал.
А очищать ее можно перед началом заполнения.

Или вариант (если есть возможность): В таблице Счета создать логическое Поле. Пробежать таблицу Счета циклом и заполнить Поле := True/False в зависимости от выполнения условий. Затем просто отфильтровать Счета по Полю.
1
 Аватар для Vyazan
12 / 12 / 2
Регистрация: 19.03.2012
Сообщений: 175
10.08.2017, 17:34  [ТС]
Цитата Сообщение от kavasaka Посмотреть сообщение
В таблицу я бы писал только 1 поле id из таблицы Счета. И только те id которые удовлетворяют всем этим длинючим условиям из where. А потом JOIN этой таблицы с Счетами - отсеет из Счетов все прочие строки. т.е. получаем то же что мог бы сделать запрос если бы работал.
А очищать ее можно перед началом заполнения.
Мысль!
Цитата Сообщение от kavasaka Посмотреть сообщение
Или вариант (если есть возможность): В таблице Счета создать логическое Поле. Пробежать таблицу Счета циклом и заполнить Поле := True/False в зависимости от выполнения условий. Затем просто отфильтровать Счета по Полю.
Хорошая идея! Спасибо за мысль.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.08.2017, 17:34
Помогаю со студенческими работами здесь

Обработка длинного запроса
Здравствуйте. Есть функция добавления данных в БД. Таблица состоит из 10 столбцов, поэтому получается, что строка достаточно длинная. Как...

Перевод на новую строку длинного SQL-запроса
Пишу SQL запрос, он очень длинный,как продолжить его на новой строке? Спасибо!

Создание БД Access, используя VB-команду Select Microsoft Access Database to Create
Доброе время суток всем!!!! все как обычно, в последнии дня....Прошу, просто умоляю ПОМОГИТЕ!!!! Сказанно сделать курсач в универ, а...

Составление Select запроса
Здравствуйте. Подскажите как сделать так, что б для тех клиентов, у которых нет покупок выводился 0 а не NULL. -- Для каждого...

Обработка запроса SELECT
$res = mysql_query("SELECT `second_id` FROM `contacts` WHERE `first_id` = 121"); $array1 = mysql_fetch_row($res); В...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru