Форум: "Базы";
Текущий архив: 2007.07.01;
Скачать: [xml.tar.bz2];
ВнизSQL запрос на поиск ну очень большого числа значений. Найти похожие ветки
← →
Arsenija © (2007-04-02 17:55) [0]Имеется таблица test, в которой имеется два столбца (Фамилия и идентификационный номер-ID (уникальное поле). Имеем список искомых ID.
Формируем запрос:
select * from test.dbf where ID IN ("01100300098456","01590506704404","01590506693664","01100300098621","0110030036 2928","01100300127032".................)
Вопрос: если список искомых значений большой (более 10 тыс.), то как сформировать запрос?
← →
StriderMan © (2007-04-02 18:40) [1]воспользуйся временной таблицей. закачай туда ID-шники.
далееSELECT T.* FROM TEST.DBF T JOIN TMP_ID.DBF I ON I.ID = T.ID
Иначе зло.
← →
StriderMan © (2007-04-02 18:55) [2]кстати, а изначально откуда ID-шники берутся? не юзер же > более 10 тыс вводит?
← →
Arsenija © (2007-04-03 09:52) [3]список искомых ID берется из файла
← →
Sergey13 © (2007-04-03 10:06) [4]> [0] Arsenija © (02.04.07 17:55)
А что ты дальше будешь с полученным списком найденных делать? Почему нельзя искать в цикле по очереди. 10000 итераций цикла - не так уж и много.
← →
Arsenija © (2007-04-03 10:30) [5]Полученный список просто выведу в DBGrid. 10тыс итераций цикла не много, но база в которой ищется велика (примерно на 10-100 млн записей)
← →
Arsenija © (2007-04-03 10:31) [6]к тому же она юзается постоянно не только мной, поэтому время поиска хотелось бы уменьшить до минимума.
← →
Sergey13 © (2007-04-03 10:37) [7]> [5] Arsenija © (03.04.07 10:30)
> Полученный список просто выведу в DBGrid.
То-то пользователь наверное обрадуется. 10000 записей - просто посмотреть и то с утра до обеда листать будет. 8-)
Может что в подходах к юзерскому интерфейсу поменять?
← →
StriderMan © (2007-04-03 10:38) [8]
> Arsenija © (03.04.07 10:30) [5]
> Полученный список просто выведу в DBGrid.
поэтому с
> в цикле по очереди. 10000 итераций цикла - не так уж и много
не получится. как один датасет в итоге получить? MemDataSet использовать? вообще не выход.
Короче я за временную таблицу.
Можно конечно вывернуться, написать ХП, парметром в нее строку бесконечной длины. Кстати СУБД какая? Если IB/FB то строки там 255 символов, не больше. придется БЛОБ-ом передавать, и в ХП его парсить.
Короче временная таблица на мой взгляд самое оно.
← →
ЮЮ © (2007-04-03 10:40) [9]>Полученный список просто выведу в DBGrid. 10тыс
А чего так себя, любимого, так ограничивать - 100 млн. в гриде гораздо впечатлительней :)
>>кстати, а изначально откуда ID-шники берутся? не юзер же > более 10 тыс вводит?
>список искомых ID берется из файла
А файл откуда берется? Почему интересуют именно эти 10 тыс? Зачем все сразу? Почему не ограничиьтся поиском действительно нужных(естественно, небольшого числв) из 100 млн?
← →
Arsenija © (2007-04-03 10:50) [10]Sergey13
"То-то пользователь наверное обрадуется. 10000 записей - просто посмотреть и то с утра до обеда листать будет. 8-)" - вероятность что записи будут найдены достаточно минимальна. Другими словами 10тыс записей проверяются на предмет повтора (уникальности) перед ихи добавлением в таблицу. поэтому как правило поиск дает либо мало записей либо совсем ничего.
"Может что в подходах к юзерскому интерфейсу поменять?" - не понял мысль, поясни пожалуйста.
StriderMan
СУБД - FoxPro. Насчет временной таблицы - похоже это выход, я в принцыпе и заткнулся на длине (символьной и размерах искомого множества) SQL запроса. Если можно поподробнее про временную таблицу, как ее создать или ссылку на ресурс, где это описано. Буду премного благодарен.
← →
Arsenija © (2007-04-03 10:53) [11]ЮЮ
интересуют 10 тыс значений из файла (всего в файле 10тыс), так как их потом будем добавлять в базу. Если ID не уникален будет полный безондерс.
← →
StriderMan © (2007-04-03 10:59) [12]
> Если можно поподробнее про временную таблицу, как ее создать
> или ссылку на ресурс, где это описано. Буду премного благодарен.
от FoxPro только название знаю, в руках не держал. Но суть проста: временная таблица - это такая же таблица как и все остальные, и создать ее можно точно так же как и любую другую
например что-то типаCREATE TABLE TMP_ID(ID INTEGER)
.
Если описаная задача будет выполняться регулярно, то имеет смысл эту таблицу не убивать после использования. А может быть и данные в ней стоит сохранять
← →
StriderMan © (2007-04-03 11:02) [13]
> Если ID не уникален будет полный безондерс
а не проще ли средствами БД отслеживать уникальность поля? кажется в любой СУБД есть такая возможность.
а что будете делать если такой ID уже есть?
← →
Sergey13 © (2007-04-03 11:04) [14]> [11] Arsenija © (03.04.07 10:53)
> интересуют 10 тыс значений из файла (всего в файле 10тыс)
> , так как их потом будем добавлять в базу. Если ID не уникален
> будет полный безондерс.
И зачем тогла в грид выводить? Юзер визуально должен выявить дубликаты ИД? Не смешите мои тапочки. Читайте из файла и пишите в базу с отловом исключения или с предпроверкой наличия дубликата (это хуже на таких объемах).
← →
Desdechado © (2007-04-03 11:07) [15]> Если IB/FB то строки там 255 символов, не больше.
Это гда ты такое вычитал? 32 килобайта.
← →
StriderMan © (2007-04-03 11:11) [16]
> Desdechado © (03.04.07 11:07) [15]
> Это гда ты такое вычитал? 32 килобайта.
VARCHAR(255) максимум. по крайней мере в FB 1.5 точно так.
← →
Arsenija © (2007-04-03 11:13) [17]StriderMan © (03.04.07 11:02) [13]
> Если ID не уникален будет полный безондерс
> а не проще ли средствами БД отслеживать уникальность поля? кажется в
> любой СУБД есть такая возможность.
> а что будете делать если такой ID уже есть?
У нас база. Мы в принципе знаем ее структуру. Есть кривой софт для работой с базой (добавление записей (файлы по 10 тыс), удаление из базы записей, редактирование служебных полей каждой записи). Кривизна софта заключается в том, что при добавдении он особо не заморачивается на предмет дублирования. Начинает добавлять, если запись в базе с таким ID уже существует, то прога выдает ошибку и самозакрывается. Что мы делаем тогда: ищем запись - удаляем - начинаем заново добавлять 10тыс записей. Таким образом теоретически возможно 10тыс таких процедур. Времени тратится море, тупизна полная. Хотим написать прогу проверки дублей сразу всех.
← →
Arsenija © (2007-04-03 11:16) [18]Sergey13
В будущем наверное заменим кривой буржуйский софт своим, но пока добавление в базу проиходит именно как в посте [17].
← →
Arsenija © (2007-04-03 11:18) [19]Sergey13
>Юзер визуально должен выявить дубликаты ИД?
Как это не смешно, но именно так.
← →
Sergey13 © (2007-04-03 11:21) [20]> [19] Arsenija © (03.04.07 11:18)
> Как это не смешно, но именно та
Если вы пойдете таким путем вы напишете не менее (в лучшем случае) кривой софт, чем то что работает сейчас.
Это делается проще. Создается (если его нет) уникальный индекс по ID. Вставляете по одной записи (если не заморачиваться на временной хранилище новых записей) и отлавливаете исключение о нарушении уникальности (просто пропускаете неудачные записи).
← →
StriderMan © (2007-04-03 11:28) [21]
> Что мы делаем тогда: ищем запись - удаляем - начинаем заново
> добавлять 10тыс записей
ну тогда все просто
DELETE FROM TABLE WHERE ID = :ID
вот такой запрос гоняете по всем 10 тыс. айдишникам из файла. потом добавляете что осталось. пойдет?
← →
Карелин Артем © (2007-04-03 11:30) [22]
> Sergey13 © (03.04.07 11:21) [20]
Через Exception тоже криво ловить.
← →
Sergey13 © (2007-04-03 11:33) [23]> [22] Карелин Артем © (03.04.07 11:30)
А почему прямо?
← →
Arsenija © (2007-04-03 11:47) [24]Добавляем либо 10тыс, либо ничего (в случае повтора). Формирование постфактум перечня повторов - неприемлимо. Перечень повторных записей нужен до добавления в таблицу (если имеются повторы, то возможно, что и весь файл на 10 тыс будет отозван заказчиком из производства)
← →
ЮЮ © (2007-04-03 11:55) [25]Первый этап:
В цикле по текстовому файлу выполняем запрос
select * from test.dbf where ID = :Id
Если запрос возвращает запись добавляем Id в "список" плохих: TStrings, TMemo, TListView, TDrawGrid - на выбор
Если "список" плохих не пуст диалог:
1) Завершить
2) Добавить исключая дубли
3) Добавить, заменяя инф-ию для дублей
Если пуст, то сразу 2)
P.S. + ProgerrBar красивый
← →
ANB © (2007-04-03 12:53) [26]дамс. юзер сам ищет дубли. опупеть.
Можно одним запросом их выдернуть.
Примерный план работы :
1. Создать постоянную локальную табличку только для закачки ID. Повесить на ID неуникальный индекс для скорости.
2. Парсим файл и инсертами заливаем данные в эту табличку (предположим, она называется TMP_ID). Возможно, если есть возможность, прикрутить ODBC на текстовый файл и гетероненненько одним запросом (совет имховый, без гарантии).
3. select ID, count(*) from TMP_ID group by ID having count(*) > 1 - даст все дубли в грид.
← →
Виталий Панасенко © (2007-04-03 12:54) [27]А не проще ли
> StriderMan © (03.04.07 11:02) [13]
?
Загнать эти 10000 во временную таблицу(будет быстро я думаю) и select ... from maintable m
join temptable t
on (m.id=t.id)
← →
Desdechado © (2007-04-03 12:54) [28]StriderMan © (03.04.07 11:11) [16]
Ты хоть документацию почитай, что ли. Цитата из Langiuage Reference для IB6.0• VARCHAR (n)
• n characters
• 1 to 32,765 bytes
• Character set character size determines the maximum number of characters that can fit in 32K
• Variable length CHAR or text string type
• Alternate keywords: CHAR VARYING, CHARACTER VARYING
Автору:
Если постфактум не нужен список дубликатов, то можно:
1. стартовать транзакцию
2. в цикле по тексту делать добавления
3. при ошибке уникальности запоминать проблемный ID
4. продолжать дальше по тексту
5. если после всех ID список проблемных пуст, то подтвердить транзакцию, иначе откатить и сохранить список для передачи "первоисточнику"
Все тривиально.
← →
StriderMan © (2007-04-03 13:06) [29]
> Desdechado © (03.04.07 12:54) [28]
> StriderMan © (03.04.07 11:11) [16]
> Ты хоть документацию почитай, что ли. Цитата из Langiuage
> Reference для IB6.0
я про FB говорю
> StriderMan © (03.04.07 11:11) [16]
> VARCHAR(255) максимум. по крайней мере в FB 1.5 точно так.
← →
Ильичев (2007-04-03 13:07) [30]2 ANB
2 Виталий Панасенко
ну что вы
в первом же ответе концепция такая предложена
просто автор видимо не понял сути, иначе уже бы всё сделал
← →
Desdechado © (2007-04-03 13:12) [31]StriderMan © (03.04.07 13:06) [29]
FB1.0 базируется (полностью поддерживает) IB6.0
А уж FB1.5 и подавно.
PS не стоит быть таким упертым
← →
Sergey13 © (2007-04-03 13:14) [32]> [26] ANB © (03.04.07 12:53)
> Повесить на ID неуникальный индекс для скорости.
Только под ногами мешаться будет. Один фиг все закачивать надо.
← →
StriderMan © (2007-04-03 13:23) [33]
> Desdechado © (03.04.07 13:12) [31]
> StriderMan © (03.04.07 13:06) [29]
> FB1.0 базируется (полностью поддерживает) IB6.0
> А уж FB1.5 и подавно.
> PS не стоит быть таким упертым
дело тут не в упертости, а в том что стоит наверное попробовать, а? я на эти грабли давно наступил и не раз.
попробуй ХП с параметром VARCHAR создать, и передать туда строчку более 255 символов. Вывалится Exception String Truncation
← →
ANB © (2007-04-03 13:47) [34]
> > Повесить на ID неуникальный индекс для скорости.
>
> Только под ногами мешаться будет. Один фиг все закачивать
> надо.
Группировка пошустрее работать будет.
Впрочем, не совсем понятно, где нужно искать дубли - в основной таблице и дельте или только в дельте.
← →
Desdechado © (2007-04-03 13:53) [35]> я на эти грабли давно наступил и не раз.
Может, ты наступил на них в экзотической ситуации?
Вообще "Exception String Truncation" не существует. Полный тескт ошибки такой "arithmetic exception, numeric overflow, or string truncation" и в основном он появляется от проблем с кодировкой передаваемого текста. Так что проверься, а?
> попробуй ХП с параметром VARCHAR создать, и передать туда строчку более 255 символов
Что, по-твоему, я не проверил и даю утверждения?
Вот, проверь у себя:create procedure New_Procedure (a varchar(32000))
returns (b varchar(32000))
as
begin
b = a;
suspend;
end
и вызовSELECT * FROM new_procedure(
"123456789012345678901234567890... и т.д. до, например, 300 знаков");
← →
Arsenija © (2007-04-03 14:24) [36]Господа, товарищи, друзья.
Добавлять записи в базу можно только кривым буржуйским софтом (политика фирмы и разработка своего возможна только в будущем, когда повзрослеем). Ограничения на этот процесс описаны в [17].
Посему пока стоит вопрос только о получении информации о повторении записей в базе и в файле на 10тыс (размер может меняться), который хотим добавить в базу. Если в базе уже есть записи с таким ID, то возможно два варианта: 1) сначала удаляем по полученному "черному" списку ручками записи из базы, потом делаем добавление (при условии что заказчик подтвердит повторы ID); 2) возвращаем заказчику файл на 10тыс записей для проведения работы над ошибками (с "черным" списком).
Мне кажется наиболее приемлим вариант [27], [1], [30]. Суть понял. Не понял как реализовать. Если можно поподробнее про временную таблицу, как ее создать или ссылку на ресурс, где это описано. Буду премного благодарен.
← →
Sergey13 © (2007-04-03 14:32) [37]> [36] Arsenija © (03.04.07 14:24)
Заливай все во временное хранилище. Далееselect * from Temp_Id T where exists (select 1 from big_table B where T.id=B.id)
получишь список ИД-шников которые уже есть в БД. Далее по вкусу.
← →
Виталий Панасенко © (2007-04-03 14:36) [38]Создаешь таблицу из одного поля, ИД в котором. Берешь лопатишь свой входной файл(который на 10000 строк). и ИД пишешь в эту тублицу. Затем делаешь запрос с таблице буржуйской базы, куда эти ИД должны кидаться и обьеденяешь с этой временной таблицей (хоть
> Виталий Панасенко © (03.04.07 12:54) [27]
этим вариантом воспользуйся..:-) )
в итоге запрос вернет либо пустой НД (qrySel.IsEmpty)или же такие ИД , которые есть в таблице-назначении(буржуйской) и во входном файле(из которого ИД перенесли во временную таблицу)
← →
StriderMan © (2007-04-03 14:49) [39]
> Desdechado © (03.04.07 13:53) [35]
> Вообще "Exception String Truncation" не существует. Полный
> тескт ошибки такой "arithmetic exception, numeric overflow,
> or string truncation" и в основном он
ну да, эту ошибку и имею ввиду
> > попробуй ХП с параметром VARCHAR создать, и передать туда
> строчку более 255 символов
> Что, по-твоему, я не проверил и даю утверждения?
> Вот, проверь у себя:
Да, честно сказать, этот пример работает, может действительно в чем-то экзотика была...
кстати, может проблема быть в IBX?
← →
Ильичев С.А. © (2007-04-03 16:09) [40]видимо Arsenija вводит в заблуждение слово "временная"
создать надо просто таблицу, обычную
в конце удалить за ненадобностью
или же использовать повторно, предварительно почистив
Страницы: 1 2 вся ветка
Форум: "Базы";
Текущий архив: 2007.07.01;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.006 c