| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Базы данных и репортинг > как получить значения поля без перебора по запросу |
| Автор: Lunatikus 10.9.2007, 12:36 |
| Здравствуйте.Подскажите,пожалуйста,кто знает,как после ADOQuery.open получить все значения какого-то поля списком или массивом(чтобы значения шли в строгой последовательности как выдает запрос ADOQuery)?И возможно ли это?Просто перебор 1млн. записей с помощью next затормаживает.А перебор именно для считывания этих значений и на их основе вычисления новых для последующего апдейта таблицы в базе.База MS SQL Server 2000 |
| Автор: Savek 10.9.2007, 12:44 |
| Вряд ли, да и чем массив или список лучше RecordSet-a? |
| Автор: Lunatikus 10.9.2007, 13:01 |
| чем лучше,не знаю,не работал с рекордсетом.Какие методы мне надо знать,чтобы получить любое значение любого поля,зная его номер внутри рекордсета?Еще увидел,что у него,Как и у, ADOQuery етсь понятие текущей записи(если бы из адоквери можно было вытащить значение не текущей и я бы это знал,я бы не парился со списком отдельным).Каким образом ее передвигать?Спасибо за помощь =) |
| Автор: ZeroMem 10.9.2007, 13:59 |
| Используй компоненты EhLib MemTable. Там можно указать свойство загружать ВСЕ(!!!) в массив, а потом достаточно просто получить к нему доступ. Вот только кажется там каждый элемент будет типа Variant... кажется. А вообще куском лучше не грузить. Лучше попробовать кусками этим же компонентом тягать данные. |
| Автор: Lunatikus 10.9.2007, 14:26 |
| представь себе хотя бы 10 полей типа врачар(255) в миллион строк...и все это вариант... |
| Автор: Lunatikus 10.9.2007, 15:38 |
| задача уже решена,но выполнение процеса занимает три часа минимум.А все почему?Ситуация примерно такая,без улсожнений: представьте календарь и несколько артикулов(товаров).ДЛя каждого артикула свой календарь,В котором ко дню привязан определенный остаток,прогноз(получается в минус остатка текущего),заказ(тоже в минус остатку),приход товара(в плюс).На основе этих полей надо просчитать остатки будущих дней(прогноз,заказы и приходы будущих дней известны и известен остаток на текущий день).Как я делал?В лоб.Я перебирал записи последовательно,сохранял остаток в переменную.Вычитал из нее значения из следующей записи и так далее....загрузка произошла изза того,что я каждый такой шаг выполняю запрос на запись в базу полученного остатка.А правильнее надо было бы делать один запрос в конце.Но тогда надо расчитать остатки программно опять же перебором,чтобы узнать значения поля остатка.Потому и хочу получить сразу весь список значений,чтобы работать с ним,а не использовать next,ибо это зло |
| Автор: Savek 10.9.2007, 15:54 | ||
Не совсем понятен алгоритм, но думаю этот перебор можно заменить одним запросом (знать бы структуру таблиц) |
| Автор: Lunatikus 10.9.2007, 16:08 |
| никаких таблиц.Есть запрос,результат которого-этот самый календарь на все артикулы: ---data-----------articul----ostatok----prognoz----zakaz---prihod--- 01.01.2007 A1 10 1 0 0 02.01.2007 A1 NULL 1 1 10 03.01.2007 A1 NULL 1 0 0 01.01.2007 A2 15 2 2 0 02.01.2007 A2 NULL 2 0 0 03.01.2007 A2 NULL 2 0 4 01.01.2007 A3 5 1 0 0 02.01.2007 A3 NULL 1 1 0 03.01.2007 A3 NULL 1 0 3 примерно это выдает запрос.И вот в этом наборе данных и перебираю по одной строке,считаю остаток следующей строки,записываю его апдейтом.Смещаюсь вниз,снова считаю...вот так елси бы я знал сразу все значения всех этих полей и мог к каждому элементу мгновенно доступиться,было бы проще и рациональнее.Но,увы,я не знаю другого метода,кроме как вот так,перебором с next'ом |
| Автор: Savek 10.9.2007, 16:58 | ||
Т.е это промежуточное состояние данных? Здесь нужно плясать от того что мы имеем к тому что должны получить, возможно этот запрос не самый оптимальный. |
| Автор: ALeXandrK 10.9.2007, 17:15 |
| А почему бы тебе в твой запрос не добавить стрку INSERT INTO temp, чтобы этот запрос превратился в таблицу, а потом, соответственно, следующим запросом подсчитать тебе все, что нужно и удалить временную таблицу?! Самый быстрый способо в твоем случае - это именно в запросе все считать, т.к. это будет минимальный набор телодвижений (без переходов, подсчетов, записи и т.п.), т.е. сразу очень много лишнего уберешь. |
| Автор: SergeBS 11.9.2007, 07:46 | ||||
| Lunatikus, К Delphi твои проблемы не относятся. Прочитай Грабера(Грубера) про SQL или в BOL. Есть такая штука: агрегатные функции. Например:
Догадайся, что эта строка вычислит ALeXandrK,
Не "ни тот", а "нЕ тот"! |
| Автор: Akella 11.9.2007, 08:09 |
а ты это всё на клиенте считаешь? А если алгоритм перевести в хранимку и считать на сервере.... это значительно ускорит процесс |
| Автор: Lunatikus 11.9.2007, 08:33 | ||
SergeBS, строка вычислит сумму остатков.Плин,Я ,конечно,новичок в программировании БД и составлении запросов SQL.Но не считайте меня совсем дибилом.Значит я не так задачу расписал,что ты предлагаешь мне сумму.Хотите,чтобы я показал вам запрос,который дает календарь?ну ловите.Запрос на столь сложное вычисление значения следующей строки на основе вычисленного уже значения предыдущей.Уже я сделал тему в разделе MS SQL на эту тему,как запросом сделать подобное вычисление.А теперь посмотрите на запрос,который выдает календарь.Писать все таблицы и объяснять,как создавался запрос смысла не вижу-никто не захочет разбираться во множественных связях 5 таблиц и таком вот запросе:
никто не захочет тратить время на разборку этого,или я не прав?) Добавлено через 1 минуту и 58 секунд Akella, как можно перевести в хранимую процедуру выполнение кода проги?Мне для начала тогда надо запросом вычисления сделать.А если это получится и так все будет сервер выполнять...чет я запутался... |
| Автор: kobra 11.9.2007, 12:25 | ||
| честно скозать, не понял алгоритм, но в принципе наверное это не стол важно. лично я, в любом случае сделал бы на сервере. хатя бы потому что гонять милион записеи по сети не етично. но что косается
|
| Автор: Lunatikus 11.9.2007, 12:43 |
| а как долго будет выполняться запрос лукапа в каждом шаге цикла на миллион шагов ?) |
| Автор: Akella 11.9.2007, 13:11 | ||
это у тебя на клиенте молотится? так пусть на сервере Добавлено через 3 минуты и 8 секунд просто у меня тоже стоит задача, если ты видел мой пост здесь, в БД, я начал молотить циклы на клиенте, ОООчень долго, но мне помогли это перевести на сервер (FB), процедура отрабатывает за 4-5 секунд |
| Автор: Lunatikus 11.9.2007, 13:34 |
| у меня сервер MS SQL 2000.Как можно сделать процедуру,выполняемую сервером по вычислению полей?Без запроса ведь никак.Вот и думаю теперь как сделать запросом расчеты...а так все запросы у меня сервер выполняет,конечно |
| Автор: Akella 11.9.2007, 14:45 | ||
а что MS SQL не позволяет делать выборки внутри хранимок? |
| Автор: Lunatikus 11.9.2007, 14:58 |
| конечно позволяет.Мы не так друг друга поняли =) я говорю о цикле перебора записей while...do... разве такое можно сохранить в "хранимках"? |
| Автор: ALeXandrK 11.9.2007, 15:17 | ||||
А может я очень сильно отрицаю, тогда можно и НИ |
| Автор: SergeBS 11.9.2007, 16:00 | ||
| Lunatikus, Объясни все-таки понятнее, что вычисляешь. Именно для A1, например. Берешь на 02.01.2007 ostatok, из него вычитаешь на 01.01.2007 ostatok и т.д. до конца? Я ничего из этого не понял:
Что из чего вычитается и т.п.? |
| Автор: Lunatikus 11.9.2007, 16:04 |
| вычитаю из первого ostatka (т.е. на 01.01.2007) значения полей zakaz,prognoz.Полученное значение записываю под датой 02.01.2007 запросом в таблицу.Смещаюсь на 02.01.2007 и уже из нового остатка(он сохранен в переменной) вычитаю prognoz,zakaz текущей строки.И так до самого конца.Когда наталкиваюсь на смену артикула,сбрасываю значение переменной и заменяю стоящим в текущей строке.,хранящей убывающий остаток.Понятно объясняю? |
| Автор: SergeBS 12.9.2007, 07:27 | ||
ALeXandrK,
Нельзя. НИ - только при перечислении. Lunatikus, Тогда BOL тебе в руки - CURSOR. Они как раз для таких построчных обработок сделаны. Или делай хранимку, которая будет высылать результат вычитания. БУдешь тогда смотреть только на дату и артикул - трафик сети резко упадет. И еще: если взять первый ostatok, из него вычесть суммы prognoz + zakaz для выбранного артикула, то по твоему описанию - получается сразу конечный результат. Или в описании что-то упущено. Например необходимость заполнения всех полей ostatok. |
| Автор: Lunatikus 12.9.2007, 08:06 |
| да,необходимость эта есть,не только изза того,что надо вносить новые значения остатков в каждой строке,но и потому,что вычисления надо делать до тех пор,пока остаток не станет нулем или отрицательным.НАсчет хранимок-наверное,стоит разобраться,что же это такое и как работает,буду искать... |
| Автор: Akella 12.9.2007, 09:07 | ||
сохранить в хранимке? зачем там сохранять? Хранимка пробежалась по набору данных (НД), выдала резальтат и всё и ничего хрнаить в ней не нужно, для этого есть таблицы. |
| Автор: ALeXandrK 12.9.2007, 13:18 | ||||
http://www.gramma.ru/RUS/?id=13.7. Есть там пунктик "ни для усиления отрицания" - и написано там, что обычно оно применяется, когда уже есть отрицание, а обычно не значит обязательно... Я не говорю, что ты не прав, но вот НИ мне больше по-душе в этом случае ... ну это отвлечения... Lunatikus: Так может тебе создать запрос (в том же SQL, кот. будет тебе считать и обновлять), а уже в цикле вызывать этот запрос с помощью TADOStoredProc. Всяко будет быстрее, чем использовать Next, пробегая по всем полям. |
| Автор: kobra 12.9.2007, 16:35 | ||
SergeBS правильно скозал, тут хорошо сработает курсор в курсоре. можно конечно и табличними переменними ползоватся. нужно протестить что оптимальнее будет |