Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.10.2011, 18:53   #11
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Вы дергаете в IBQuery4 и IBQuery5 в цикле небольшие кусочки информации и небольшое к-во полей. Если там не миллионы записей и нет возможности параметризировать выгрузку сразу всей нужной информации - выгрузите всю. А в программе сам расчет. Если расчет сложно так организовать, то можно ClientDataSet-ы прицепить к кверикам, в них создать необходимое к-во индексов, что значительно облегчит вашу участь и ускорит процесс расчета.
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 27.10.2011, 21:18   #12
chui
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 48
По умолчанию

Там не миллионы конечно, но под 200к будет. Попробую сделать, как вы написали.
chui вне форума Ответить с цитированием
Старый 29.10.2011, 13:44   #13
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
спасибо за советы, но все мои попытки решить одним запросом и вынести его за пределы цикла не дали результатов (в смысле нереально в данном случае это сделать на мой взгляд).
Судя по тому что запрос в приведенном коде не модифицируется (параметры не в счет), то сделать все одним запросом вполне реально (например через вложенные запросы). Покажите наконец сами запросы (оба) будет о чем говорить.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 31.10.2011, 10:01   #14
chui
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 48
По умолчанию

IBQuery4:
Код:
SELECT TOV_COUNT,TOV_COST
from T_TOVAR left join T_GTD on (TOV_GTDID = GTDID) 
where (TOV_IMPGTDNO =:param1)  and (GTDRAZR =:param2)
IBQuery5:
Код:
select TOV_COST 
from T_TOVAR left join T_GTD on (TOV_GTDID = GTDID) 
where (TOV_IMPGTDNO =:par1)  and (GTDSPRAV =:par2)
Параметр par2 не изменяется, остальные меняются. В первом запросе param2 меняется и для каждого есть еще несколько разных param1.

Еще одна сложность заключается в том, что мне для расчета одновременно необходимы данные из xml (MATCOUNT) и БД.

Последний раз редактировалось chui; 31.10.2011 в 11:40.
chui вне форума Ответить с цитированием
Старый 31.10.2011, 12:41   #15
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

1. например получить один раз
Код:
SELECT TOV_COUNT,TOV_COST, TOV_IMPGTDNO, GTDRAZR, GTDSPRAV
from T_TOVAR left join T_GTD on (TOV_GTDID = GTDID)
Без условий (либо с условиями обеспечивающим получение ВСЕХ нужных записей т.е.для ВСЕХ значений параметров из IBQuery2).
И в цикле не дергать БД много раз. А использовать внутренний поиск Locate.или фильтрацию.

2 либо отравить на сервер что-то вроде
Код:
select R2.*, R4.*, R5.* 
from (<здесь lзапрос IBQUEry2>) as R2 
left join (<IBquery4>) as R4  on <то что было в WHERE> and <доп условие что было в IF >
left join (<IBQuer5> as R5 on <то что в WHERE>
а поскольку нужна только одно то даже так
Код:
select sum (isNULL(R4.COST/R4.count),0), SUM(r5.count)
< from left предыдущего запроса >
[group by ..].
Здесь всего лишь формальное перенесение вашего кода (R2 + R4 + R5) на строну СУБД. для более точного разговора нужен текст IBquery2. подозреваю там все те таблицы T_TOVAR T_GTD. И описание ИТОГОВОЙ формулы расчета (что бы не вытаскивать ее из кода программы). таv насколько сумел понять при беглом просмотре.

sum(r4.cost/r4.count) для IBQuerty4 для тех где count>0 и это (count>0) проверятся по вашему коду в IBQuery2.
sum(r5.count) для IBQuery5.
а что в итгоге ?
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 31.10.2011 в 12:52.
evg_m вне форума Ответить с цитированием
Старый 31.10.2011, 13:06   #16
chui
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 48
По умолчанию

В IBQuery2 получаем временную таблицу (select * from MemTemp). В ней содержатся данные из xml.
Код:
<Report>
<GTDRAZR>06533/04003705</GTDRAZR>
<GTDSPRAV0>06533/300511/0023997</GTDSPRAV0>
<MSPRAV>06533/010910/4003715</MSPRAV>
<IMPGTDNO>1</IMPGTDNO>
<IMPGTDNOOSN>1</IMPGTDNOOSN>
<GCOUNTRY>РБ</GCOUNTRY>
<MCOUNTRY>528</MCOUNTRY>
<GCODE>3215190000</GCODE>
<MCODE>2909491800</MCODE>
<TCOUNT>2,141</TCOUNT>
<OT>0</OT>
<TYEAR>2010</TYEAR>
<TEI>КГ</TEI>
<CUNN>190929166</CUNN>
</Report>
И для каждой итерации мне необходимо отсюда брать TCOUNT.

Код:
mat_costone:= ((StrToFloat(IBQuery4.Fields[1].Value))/(StrToFloat(IBQuery4.Fields[0].Value)))*StrToFloat(MATCOUNT);
              matprod:= matprod + mat_costone;
В этой формуле я делю общую стоимость на общее кол-во товара (т.е. получаю стоимость за 1 единицу, данные из БД), а потом умножаю на необходимое кол-во товара (данные из xml). Потом в matprod записываю сумму всех таких вычислений пока IMPGTDNOOSN равен i. Так я получаю стоимость материалов для изготовления продукции. А IBQuery5 нужен для получения стоимости уже готовой продукции. Далее я их сравниваю.

Последний раз редактировалось chui; 31.10.2011 в 13:27.
chui вне форума Ответить с цитированием
Старый 31.10.2011, 14:18   #17
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Дополню evg_m.
Для каждой записи IBQuery2 в таблицу базы временную или постоянную (если постоянная предварительно удалить все записи) загоняем
Код:
INSERT INTO WorkTable (GTDRAZR,IMPGTDNO,MATCOUNT,IMPGTDNOOSN)
  VALUES(<GTDRAZR из IBQuery2>,<IMPGTDNO из IBQuery2>,<MATCOUNT из IBQuery2>,<IMPGTDNOOSN из IBQuery2>)
Примерный аналог IBQuery4 для всех W.IMPGTDNO, W.GTDRAZR, W.IMPGTDNOOSN
Код:
SELECT W.IMPGTDNO,W.GTDRAZR,W.IMPGTDNOOSN,
    SUM(CAST(TOV_COST AS NUMERIC(15,2))/CAST(TOV_COUNT AS NUMERIC(15,2))*CAST(W.MATCOUNT AS NUMERIC(15,2))) as matprod
  from WorkTable W,T_TOVAR
    left join T_GTD on (TOV_GTDID = GTDID)
  where (TOV_IMPGTDNO=W.IMPGTDNO) and (GTDRAZR=W.GTDRAZR)
  GROUP BY W.IMPGTDNO,W.GTDRAZR,W.IMPGTDNOOSN
Преобразование типов сделаете как допустимо в СУБД. Аналогично можно поступить с IBQuery5. Сильно не анализировал, возможно и его можно засунуть в выше приведенный запрос. Bcя информация выбрана без циклов. Дальше расчет
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 31.10.2011 в 15:03.
Аватар вне форума Ответить с цитированием
Старый 31.10.2011, 18:10   #18
chui
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 48
По умолчанию

Аватар, спасибо. Попробую.
chui вне форума Ответить с цитированием
Старый 01.11.2011, 11:22   #19
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

весь расчет в одном запросе Как прийти к такому коду написано в комментариях.(---- )
Код:
select GTDRAZR, GTDSPRAV0, MSPRAV, IMPGTDNO
, R5.tov_cost, Rcompl.calc -- посчитанные значения
----, IMPGTDNOOSN, TCOUNT , GCOUNTRY, MCOUNTRY, GCODE, MCODE, OT, TYEAR, TEI прочие поля  
from templ as R2  ---список изделий 
left join ( -- стоимость изделия
            select TOV_COST, --стоимость
            TOV_IMPGTDNO, GTDSPRAV --изделие
            from T_TOVAR left join T_GTD on (TOV_GTDID = GTDID) 
          ) as R5 on R5.TOV_IMPGTDNO =R2.IMPGTDNO and R5.GTDSPRAV =R2.GTDSPRAVNO

left join ( -- стоисмость комплектующих
            select Sum(price* TCount) as calc --стоимость
            , GTDRAZR, IMPGTDNO --изделие для которого используется
            from templ as R2 --комплектующие для изделия 
            inner join ( --стоимость отдельных комплектующих
                         SELECT TOV_COUNT/TOV_COST as Price, TOV_IMPGTDNO, GTDRAZR
                         from T_TOVAR left join T_GTD on (TOV_GTDID = GTDID) 
                       ) R4 on R4.TOV_IMPGTDNO =R2.IMPGTDNO  and R4.GTDRAZR =R2.GTDRAZR
            where R2.IMPGTDNOOSN =1 --только комплектующие
            group by GTDRAZR, GTDSPRAV0 --общая стоимость комплектующих
          ) Rcompl on Rcompl.IMPGTDNO =R2.IMPGTDNO and Rcompl.GTDSPRAV =R2.GTDSPRAVNO
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 01.11.2011 в 11:25.
evg_m вне форума Ответить с цитированием
Старый 01.11.2011, 12:04   #20
chui
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 48
По умолчанию

evg_m, спасибо. Только меня смущает строчка
Код:
where R2.IMPGTDNOOSN =1 --только комплектующие
IMPGTDNOOSN не всегда будет = 1.

И templ это временная таблица?

Последний раз редактировалось chui; 01.11.2011 в 13:07.
chui вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Запрос с параметрами us4us SQL, базы данных 1 20.05.2011 05:53
программа с типизированными параметрами-значениями и параметрами-переменными Kira09 Паскаль, Turbo Pascal, PascalABC.NET 1 20.12.2010 22:23
Запрос с CASE переделать в запрос с PIVOT (MS SQL Server 2005) Машуля SQL, базы данных 4 06.05.2010 21:09
Запрос с изменяющимися параметрами GenniY БД в Delphi 10 18.03.2010 14:41