|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
В курсоре t1_al имеются поля dnei, dn_per, op_pozakr. Dnei – количество дней опозданий по переносу карточки и + по закрытию. dn_per – количество дней опозданий по переносу. op_pozakr - количество дней опозданий по закрытию. Все поля необходимые для заполнения курсора t1_al, заполняются в курсоре perenosy (поля в курсоре sum_per, sum_op_zakr, sum_nn) Вопрос: Как данные из курсора perenosy записать в курсор t1_al ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2011, 15:14 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
Allkay, Кто будет участвовать огромное спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2011, 15:29 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
Allkay, есть два пути: 1. Если необходимые данные есть в курсоре perenosy, то пишешь: Код: plaintext
create cursor t1_al (dnei N(3,0), dn_per N(3,0), op_pozakr N(3,0)) <здесь готовятся необходимые данные> insert into t1_al values (...., ...., ....) ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2011, 07:01 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
Как заполнить курсор, в принципе понятно, проблема в том, как сохранить данные, (Извлечь данные подсчета) из алгоритма подсчета. Ведь те данные, что мне нужны, существуют на этапе подсчета в алгоритме (Алгоритм подсчета дней) после окончания подсчета их нет (если остается то только последняя запись). Для заполнения курсора t1_al, нужно, на этапе подсчета в курсоре perenosy, запоминать данные, чтобы по окончании подсчета из памяти заполнить t1_al. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2011, 13:37 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
БД ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2011, 15:22 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
Allkay, данные в курсоре _никогда_ сами собой не сохранятся он живет только пока не закончиться сеанс работы либо Вы его не убъете явно внутри алгоритма курсор _по_определению_ - временная штука если Вам надо именно хранить информацию - либо пользуйтесь таблицами сразу либо в нужный момент скидывайте все из курсора в таблицу sele * from курсор into table таблица как вариант - скидывайте из курсора в уже имеющуюся таблицу данные периодически insert into таблица sele * from курсор where условиеотборанужныхстрок ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2011, 16:54 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
Есть еще какие ни будь варианты? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.10.2011, 09:51 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
Allkay, Да, есть другие варианты Нарисовать алгоритм карандашом на бумаге, его обдумать, еще раз обдумать - уже тщательно. Переделать с нуля всю логику проги и структуру БД. Потому что даже начало "Dnei – количество дней опозданий по переносу карточки и + по закрытию. dn_per – количество дней опозданий по переносу." говорит о том, что и программа, и база у Вас скоро будут представлять собой "Тришкин кафтан" - объем заплаток и доковырок превысит объем собственно самой работы. Уж не знаю - зачем это все держать в курсорах, кстати, и как Вы в таких случаях обходите коллизии, но советую начать хотя бы с "Dn_zak – количество дней по закрытию. dn_per – количество дней опозданий по переносу.", а финты типа "поле равно другое поле плюс икс" - позабыть как можно скорей... ... |
|||
:
Нравится:
Не нравится:
|
|||
05.10.2011, 14:14 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
SSn888, Выход, я, кажется, нашел, и как не странно с помощью курсора. Создал в начале алгоритма подсчета дней, курсор, затем в процессе подсчета количества дней заполнял новый курсор. На выходе получилось, мне нужный курсор t1_al, для заполнения отчета, и новый курсор заполненный данными. Осталось только заполнить курсор t1_al из нового курсора. А что плохого в ворожении: поле = поле + х ? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.10.2011, 09:58 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
Примерно ток. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.10.2011, 10:00 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
Allkay, извините, только ща нормально добрался до компа на выходных отвечу ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2011, 22:57 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
AllkayКак заполнить курсор, в принципе понятно, проблема в том, как сохранить данные Сохраняйте INTO TABLE или INTO ARRAY либо селектом, либо по мере их вычисления процедурно (REPLACE TempTable.pole1 WITH a1 или TempArray[1]=a1). ... |
|||
:
Нравится:
Не нравится:
|
|||
08.10.2011, 20:11 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
Allkay Хотел просто прислать Вам слегка измененный Ваш ше текст, но споткнулся о то, что не совсем уверен в своем понимании смысла полей :) Почему отпишу тут... Просьба не воспринимать как критику вроде "почему без шапки" :) 0) "А что плохого в ворожении: поле = поле + х ?" Почитайте про нормализацию 1) В фоксе есть возможность переноса части строки по желанию, табы и прочее. Пользуйтесь все-таки этим для того, чтоб текст не представлял собой кашу, так и Вам самому будет удобней... например, сравните SELECT Pointtask.regnumb, Pointtask.pointnumb, Pointtask.pointsod, Pointtask.dateout, ; {..} as datenew, Pointtask.datefact, Pointtask.datecansel, Pointtask.datemarke, ; и SELECT PointTask.pointNumb,; PointTask.pointSod,; PointTask.dateOut,; PointTask.dateFact,; PointTask.dateCansel,; PointTask.dateMarke,; IIF(EMPTY(PointTask.dateNew),; PointTask.dateOut,; PointTask.dateNew) AS d_n, ; IIF(EMPTY(PointTask.dateFact) OR PointTask.dateFact>datt_ok,; datt_ok, PointTask.dateMarke) AS d_mkk,; PointTask.tabMark,; PointTask.tabReg; FROM PointTask; WHERE (PointTask.regNumb == lcRegNumb); INTO CURSOR crsPointTask; ORDER BY pointSod 2) Если посмотреть на содержимое полей в первом Вашем запросе и их наличию в объединяемых таблицах - то приходит мысль, что UNION тут как раз не совсем нужен, лучше как-то обыграть JOIN, нет нужды городить "шахматку" 3) Формула nn = t1_al.d_mkk - (t1_al.d_n) реально работает только для PointTask, давая nn = IIF(EMPTY(PointTask.datefact) OR PointTask.datefact>datt_ok,; datt_ok,; PointTask.datemarke) -; IIF(EMPTY(PointTask.datenew),; PointTask.dateout,; PointTask.datenew) Для PointMove в любом раскладе будет nn = {..} - {..} Причем данные зависят только от инфы в курсоре, никаких "внешних влияний" нет Тогда зачем это все считать в скане, а не просто вынести в первый запрос как вычисляемое поле? 4) Поле regn, формрируемое по принципу (ALLTRIM(pointtask.regnumb)+'('+ALLTRIM(pointtask.pointnumb)+')') и далее по той же логике используемое для сравнения - абсолютно излишне, бо часть regnumb его вообще-то выходит константой, для сравнения и прочего вполне достаточно pointnumb (В самом начале указывается lcRegNumb ='21066001' и курсор формируется с WHERE PointTask.regnumb = lcRegNumb... то есть - по логике - в дальнейшей части блока поле regnumb вообще не нужно как факт) 5) Селект внутри цикла в этой ситуации... эээ... во-первых - слишком неизящно, во-вторых - может довести до безобразия. На каждую запись курсора1 (сформированного из 2 источников) приходится обработка всех записей курсора2... как - нет торможения проги даже на тесте? Как понимаю - этот хитрый путь возник из суровой необходимости - ведь надо брать данные dat_perper для следующей записи из предыдущей. В запросе это сразу написать - легче застрелиться. Есть способ "объехать на кривой козе", устроив самообъединение со сдвигом 1. Добавляем столбец-нумератор ну, например, SELECT *, recno() AS rcn FROM .... 2. Делаем копию результата (на самом деле - это все можно сделать и без копии, слегка укрупнив запрос, но грузить не буду) SELE * FROM A1 TO A2 3. Сливаем SELECT A1.datenew AS d_n1,; A1.. ... A2.datenew AS d_n2; && то, что ранее пихал в dat_perper в цикле FROM A1; LEFT JOIN A2; ON (A1.rcn +1 == A2.rcn ) INTO..... 4. Выкидываем то, что уже "отработано" - убиваем курсоры A1 & A2 5. Всю алгебру/геометрию из цикла переносим в запрос как вычисляемые поля 6) Собственно - если у Вас результат всей этой обработки идет _только_ в отчет - нет нужды в половине всей этой обработки Подсчет количеств и прочее удобней реализовать внутри самого отчета В меню report зайти в variables, добавить переменную, выбрать нужный calculationtype и так далее... в отчете просто добавить объект поле с этой переменной ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2011, 12:59 |
|
Заполнение курсора из другого курсора
|
|||
---|---|---|---|
#18+
SSn888, SSn888 Спасибо за помощь, я как говорил нашел выход и поэтому не проверял форум. А ответ вот какой он: *Выбор исходных данных (Основной курсор) SELECT Pointtask.pointnumb, Pointtask.pointsod, Pointtask.dateout, ; {..} as datenew, Pointtask.datefact, Pointtask.datecansel, Pointtask.datemarke, ; 000000 as dnei, 000000 as dn_per, 000000 as op_pozakr, ; (ALLTRIM(pointtask.regnumb)+'('+ALLTRIM(pointtask.pointnumb)+')') as regn, ; IIF(EMPTY(pointtask.datenew), pointtask.dateout, pointtask.datenew) as d_n, ; IIF(EMPTY(pointtask.datefact) OR pointtask.datefact>datt_ok, datt_ok, pointtask.datemarke) as d_mkk, ; Ispleader.fio as fiomark, Abonent.fio as fioreg ; FROM bduaski!Pointtask ; LEFT OUTER JOIN bduaski!ispleader ; ON Pointtask.tabmark = Ispleader.tabel ; LEFT OUTER JOIN bduaski!abonent ; ON Pointtask.tabreg = Abonent.tabel ; WHERE Pointtask.regnumb = lcRegNumb ; UNION ; SELECT Pointmove.pointnumb, " " as pointsod, {^2199.12.31} as dateout,; Pointmove.datenew, {..} as datefact, {..} as datecansel, Pointmove.datemarke, ; 000000 as dnei, 000000 as dn_per, 000000 as op_pozakr, ; " " as regn, {..} as d_n, {..} as d_mkk, ; Ispleader.fio as fiomark, Abonent.fio as fioreg ; FROM bduaski!Pointmove ; LEFT OUTER JOIN bduaski!ispleader ; ON Pointmove.tabmark = Ispleader.tabel ; LEFT OUTER JOIN bduaski!abonent ; ON Pointmove.tabreg = Abonent.tabel ; WHERE Pointmove.regnumb = lcRegNumb ; ORDER BY 1,3 INTO CURSOR t1_al READWRITE *Создание курсора CREATE CURSOR pointtask2 (pointnumb C(9), datenew D(8), datemarke D(8), kol_dn_op N(10), kol_dn_oprab N(10), sum_kol_dn_oprab N(10)) *Алгоритм подсчёта дней SELECT t1_al SCAN *Селект собирающий все переносы по текущей карте SELECT pointmove.pointnumb, pointmove.datenew, pointmove.datemarke, 000000 as kol_dn_op, 000000 as kol_dn_oprab, 000000 as sum_kol_dn_oprab ; FROM pointmove WHERE ALLTRIM(pointmove.regnumb)+'('+ALLTRIM(pointmove.pointnumb)+')'=t1_al.regn INTO CURSOR perenosy READWRITE ORDER BY 1,3 SELECT perenosy GO TOP *Подсчёт общего числа переносов kol_per=RECCOUNT() *Подсчёт Опоздания по переносам op_per=0 *Подсчёт Опоздания по закрытию, или не закрыта а должна op_zakr=0 *Если есть переносы, выполняется: IF kol_per>0 *Запоминаем дату када должен был быть первый перенос (дата первого переноса это -- дата выполнения) dat_perper = t1_al.dateout FOR i=1 TO kol_per *Если есть опоздания, т.е. дата выполнения меньше даты отметки (SKIP 1) IF dat_perper < perenosy.datemarke *Считаем кол-во дней опоздания nn = perenosy.datemarke - (dat_perper) REPLACE perenosy.kol_dn_op WITH nn *Выключен подсчёт рабочих дней nn = nn-3 *Если nn < 0 значит опозданий нет IF nn < 0 nn = 0 ENDIF *Проссумировали дни опоздания op_per = op_per + nn REPLACE perenosy.kol_dn_oprab WITH nn REPLACE perenosy.sum_kol_dn_oprab WITH op_per *Заполнение курсора данными из другого курсора *SELECT perenosy *GO TOP *IF !EOF() INSERT INTO Pointtask2 (pointnumb, datenew, datemarke, kol_dn_op, kol_dn_oprab, sum_kol_dn_oprab); VALUES (perenosy.pointnumb, perenosy.datenew, perenosy.datemarke, perenosy.kol_dn_op, perenosy.kol_dn_oprab, perenosy.sum_kol_dn_oprab) *ENDIF ENDIF *Присвоение (следующего) начального значения для даты переноса dat_perper = perenosy.datenew *Перемещаемся на след по времени перенос SKIP *Выход из цикла если больше нет переносов ENDFOR ENDIF *Были или нет переносы,считаем колво дней опозданий с даты начала подсчёта(dateout или datenew <соответствует последнему переносу>) nn = t1_al.d_mkk - (t1_al.d_n) nn = nn - 3 IF nn < 0 nn = 0 ENDIF op_zakr = op_zakr + nn *Заполняем главную таблицу SELECT t1_al *Заносим подсчитанные дни опоздания ( t1_al -- заполняется во время выполнения цикла ) REPLACE t1_al.dnei WITH op_per + op_zakr, t1_al.dn_per WITH op_per, t1_al.op_pozakr WITH nn ENDSCAN *Заполнение курсора t1_al курсором Pointtask2* SELECT t1_al.pointnumb, t1_al.pointsod, t1_al.dateout, ; t1_al.datenew, t1_al.datefact, t1_al.datecansel, t1_al.datemarke, ; t1_al.dnei, t1_al.dn_per, t1_al.op_pozakr, ; t1_al.fiomark, t1_al.fioreg, ; Pointtask2.kol_dn_op, Pointtask2.kol_dn_oprab, Pointtask2.sum_kol_dn_oprab ; FROM t1_al ; LEFT OUTER JOIN Pointtask2 ; ON t1_al.pointnumb=Pointtask2.pointnumb AND t1_al.datenew=Pointtask2.datenew ; ORDER BY 1,3 INTO CURSOR expPoint READWRITE *Последний селект для заполнения отчета* SELECT expPoint.pointnumb, expPoint.pointsod, ; IIF(expPoint.dateout={^2199.12.31},{..},expPoint.dateout) as dateout, ; expPoint.datenew, expPoint.datefact, expPoint.datecansel, expPoint.datemarke, ; expPoint.dnei,; IIF(expPoint.dn_per<expPoint.kol_dn_oprab, expPoint.kol_dn_oprab, expPoint.dn_per) as dn_per, ; expPoint.op_pozakr, ; expPoint.fiomark, expPoint.fioreg ; FROM expPoint ; INTO CURSOR expert READWRITE ... |
|||
:
Нравится:
Не нравится:
|
|||
21.10.2011, 10:16 |
|
|
start [/forum/topic.php?fid=41&msg=37470395&tid=1584057]: |
0ms |
get settings: |
11ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
30ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
others: | 15ms |
total: | 139ms |
0 / 0 |