Помогите пожалуйста решить задачу

все вопросы и ответы о среде для разработчиков от www.sqlly.com

Модераторы: kdv, Pavel Kutakov

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 12 сен 2007, 22:52

Клиника просто. Ты всерьёз думаешь, что сервер посылает записи клиенту поштучно? :shock: И что "массив" он захреначит в один TCP пакет?

ERrorMAKros
Сообщения: 37
Зарегистрирован: 18 янв 2007, 01:05

Сообщение ERrorMAKros » 12 сен 2007, 23:37

...нет, но хочется проделать как можно меньше операций в сторону сервера, хотелось что бы сервер вернул мне готовый блок данных в удобном мне формате и делай с ним что хочешь. Что бы алгоритм задачи был более "мобильны в разработке" что ли... Та уже понятно что придеться все перебирать, запись за записью... скучно, я ожидал от interbase больше спецэффектов =)

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 12 сен 2007, 23:49

Если результат таблицы выдаст 1000 записей, придется делать progressbar и пользователь будет "втыкать" в монитор пока процес не пройдет от первой и до последней 1000`ной записи. Вот я и ищу способ, что бы не перебирать по одной записи, а получить от сервера результат в удобном мне виде
а если он выдаст 100000 записей? Как ты думаешь, сервер сможет зафигачить такой массив, и передать его тебе "одним махом"?
скучно, я ожидал от interbase больше спецэффектов
понятно. т.е. все что тебе отвечали, ты читал невнимательно.
тебе не кажется, что если за 20 лет до такой фигни не додумались, то проблема не в сервере, а в твоих странных пожеланиях? Было бы это "эффективно" - уж давно бы сделали, и не только в IB/FB.

ERrorMAKros
Сообщения: 37
Зарегистрирован: 18 янв 2007, 01:05

Сообщение ERrorMAKros » 13 сен 2007, 00:26

...ну это еще спорный вопрос, потому как, например, в delphi операции с динамическими данными бывают разные, ...иногда с внушающими размерами, тут мы много от чего не застрахованы. Если же додумались в БД впихнуть интерпретатор, ...то можно было бы и поэкспериментировать, ...но видимо эксперименты собираются открывать по одной-две-четыре штуке, постепенно, ...в новых версиях. Но в любом случае Большое спасибо за поддержку топика!!!!

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 13 сен 2007, 00:35

В общем, диагноз ясен. :roll:
Чего хочешь - представляешь пока смутно, но главное, чтобы "Ух!!!". "Спецеффекты", так сказать.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 13 сен 2007, 01:21

но видимо эксперименты собираются открывать по одной-две-четыре штуке, постепенно, ...в новых версиях
и не надейся. я что-то за 12 лет не припомню, чтобы кто-то еще вот так хотел - "раз, и в массив". это ведь совершенно частная задача, для клиент-сервера на 99.999% не подходящая.

хотя, можешь соорудить трехзвенный сервер, который будет принимать записи с сервера БД, оформлять в массив, и передавать в твое приложение. Это накорябать можно очень быстро, даже имеющимися средствами (тот же midas).

ERrorMAKros
Сообщения: 37
Зарегистрирован: 18 янв 2007, 01:05

Сообщение ERrorMAKros » 15 сен 2007, 16:14

Люди , помогите пожалуйста разобраться в процедуре , ...т.к. только у вас смогу спросить многие мелочи и сложновато перестроиться на др. синтаксис языка после pascal , ...нашел себе мучения на св. голову.

Есть вот такой вот код на delphi:

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
    const TABLE_RECORDS    = 003; // макс длинна массива
                                                                                     {сутки , деньги}
          IBLINE_AGENTS_DEMURRAGE: array [000..TABLE_RECORDS , 000..001] of integer=((    7,     0) , 
                                                                                     (    7,     8) , 
                                                                                     (   14,    16) , 
                                                                                     (  100,    20));
          DAYSPRESENT    = 035;     // общее кол-во имеющихся дней
      var counter_days   : integer; // контрольный счетчик дней; контроль от 0 до DAYSPRESENT;
          get_moneys     : integer; // суммирование последующего полученного денежного числа с массива;
          cycle_array    : integer;
          cycle_array_itm: integer;

    begin counter_days   :=000; // счетчик суток;
          get_moneys     :=000; // суммирование денег;
      for cycle_array    :=000 to TABLE_RECORDS                            do // общая длинна записей всего массива;
      for cycle_array_itm:=001 to IBLINE_AGENTS_DEMURRAGE[cycle_array , 000] do // длинна ячейки "сутки" в cycle_array эллементе массива;

       if(DAYSPRESENT>counter_days   )
     then begin get_moneys:=get_moneys+IBLINE_AGENTS_DEMURRAGE[cycle_array , 001];
                inc(counter_days);
                end
     else break;
          memo1.Lines.Text:='Moneys count: '+IntToStr(get_moneys);
          end; // procedure
Получаем:

Код: Выделить всё

на протяжении DAYSPRESENT (35 cуток) осуществляется оплата за:
за первые 7 суток из DAYSPRESENT ( 1) (  1) получаем =   0$
                  по  0$         ( 2) (  2) получаем =   0$
                                 ( 3) (  3) получаем =   0$
                                 ( 4) (  4) получаем =   0$
                                 ( 5) (  5) получаем =   0$
                                 ( 6) (  6) получаем =   0$
                                 ( 7) (  7) получаем =   0$ = сумма первых пройденных 7 (из DAYSPRESENT (35 cуток)) суток
за сл.    7 суток из DAYSPRESENT ( 8) (  1) получаем =   8$
                  по  8$         ( 9) (  2) получаем =  16$
                                 (10) (  3) получаем =  24$
                                 (11) (  4) получаем =  32$
                                 (12) (  5) получаем =  40$
                                 (13) (  6) получаем =  48$
                                 (14) (  7) получаем =  56$ = сумма сл. пройденных 7 (из DAYSPRESENT (35 cуток)) суток
за сл.   14 суток из DAYSPRESENT (15) (  1) получаем =  72$
                  по 16$         (16) (  2) получаем =  88$
                                 (17) (  3) получаем = 104$
                                 (18) (  4) получаем = 120$
                                 (19) (  5) получаем = 136$
                                 (20) (  6) получаем = 152$
                                 (21) (  7) получаем = 168$
                                 (22) (  8) получаем = 184$
                                 (23) (  9) получаем = 200$
                                 (24) ( 10) получаем = 216$
                                 (25) ( 11) получаем = 232$
                                 (26) ( 12) получаем = 248$
                                 (27) ( 13) получаем = 264$
                                 (28) ( 14) получаем = 280$ = сумма сл. пройденных 14 (из DAYSPRESENT (35 cуток)) суток
за сл.  100 суток из DAYSPRESENT (29) (  1) получаем = 300$
                  по 20$         (30) (  2) получаем = 320$
                                 (31) (  3) получаем = 340$
                                 (32) (  4) получаем = 360$
                                 (33) (  5) получаем = 380$
                                 (34) (  6) получаем = 400$
                                 (35) (  7) получаем = 420$ = cумма оставшихся 7 из 35 суток;
                                 (36) (  8) получаем = дальшне не считаем
                                 (37) ( ..) получаем = дальшне не считаем
                                 (38) ( ..) получаем = дальшне не считаем
                                 (39) (100) получаем = дальшне не считаем

в сумме по тарификации получается 420$
это схема поставленной задачи , ...аналогичное нужно реализовать
как ХП. Написал вот такой вот вариант , прошу помочь отладить!

Код: Выделить всё

CREATE PROCEDURE GET_DEMURRAGE("LINECODE"         INTEGER   ,    /* флаг ID компании                   */
                                "CONTNUM"          VARCHAR(20) , /* тип контейнера [40`GP, 20`GP]      */
                                "DAYSPRESENT"      INTEGER)      /* общий промежуток дней              */
RETURNS                        ("DEMURRAGE_MONEYS" INTEGER)      /* результат подсчета                 */

     AS DECLARE VARIABLE "GET_DAYCOUNT"  INTEGER; /* КОЛ-ВО  СУТОК */
        DECLARE VARIABLE "GET_SALARY"    INTEGER; /* КОЛ-ВО  ДЕНЕГ */
        DECLARE VARIABLE "INC_DAYCOUNT"  INTEGER; /* СЧЕТЧИК СУТОК */
        DECLARE VARIABLE "INC_MONEYS"    INTEGER; /* СЧЕТЧИК ДЕНЕГ */
        DECLARE VARIABLE "CYCLE"         INTEGER; /* ЦИКЛ          */

  BEGIN       INC_DAYCOUNT=000;
    FOR
 SELECT       IBLINE_AGENTS_DEMURRAGE."DEM_DAYSCOUNT" ,
              IBLINE_AGENTS_DEMURRAGE."DEM_SALARY"
   FROM       IBLINE_AGENTS_DEMURRAGE
  WHERE      (IBLINE_AGENTS_DEMURRAGE."DEM_LINECODE" =:LINECODE)
    AND      (IBLINE_AGENTS_DEMURRAGE."DEM_CONTNUM"  =:CONTNUM)
  ORDER  BY   IBLINE_AGENTS_DEMURRAGE."DEM_STEPINC"
   INTO      :GET_DAYCOUNT ,
             :GET_SALARY
         DO   BEGIN 
              WHILE(CYCLE<GET_DAYCOUNT-001)
                 DO BEGIN
                 IF(DAYSPRESENT>INC_DAYCOUNT)
               THEN BEGIN INC_MONEYS  = INC_MONEYS+GET_SALARY;
                          INC_DAYCOUNT= INC_DAYCOUNT+001;
                          END /* IF..     */
                          CYCLE=CYCLE+001;
                          END /* WHILE... */
                          END /* FOR...   */
                          DEMURRAGE_MONEYS=INC_MONEYS;
                          SUSPEND;
                          ENd 
Архитектура самой таблицы:

Код: Выделить всё

CREATE TABLE IBLINE_AGENTS_DEMURRAGE
(
AINC             INTEGER      DEFAULT NULL ,    /* инкримент
DEM_LINECODE     INTEGER      DEFAULT NULL ,    /*(ПРИВЯЗКА) КОД ЛИНИИ;
DEM_CONTNUM      INTEGER      DEFAULT NULL ,    /*(ПРИВЯЗКА) ТИП КОНТЕЙНЕРА;
DEM_STEPINC      INTEGER      DEFAULT NULL ,    /* ПОСЛЕДОВАТЕЛЬНОСТЬ;
DEM_DAYSCOUNT    INTEGER      DEFAULT NULL ,    /* СУТКИ;
DEM_SALARY       INTEGER      DEFAULT NULL ,    /* ДЕНЬГИ;
DEM_CURR         VARCHAR(255) DEFAULT NULL ,    /* ВАЛЮТНОЕ СЧИСЛЕНИЕ;
DEM_COMMENT      VARCHAR(255) DEFAULT NULL);  /* КОМЕНТ;
В НЕОТСОРТИРОВАННОМ ВИДЕ ТАБЛИЦЫ ВЫГЛЯДИТ ТАК:

Код: Выделить всё

| AINC | DEM_LINECODE | DEM_STEPINC | DEM_DAYSCOUNT | DEM_SALARY | DEM_CURR | DEM_CONTNUM | DEM_COMMENT
|   49 |           48 |           1 |             7 |          0 |    ДОЛЛ. |       20`GP | FREE  7 (ДНЕЙ)
|   50 |           48 |           1 |             7 |          0 |    ДОЛЛ. |       40`GP | FREE  7 (ДНЕЙ)
|   53 |            2 |           1 |            14 |          0 |    ДОЛЛ. |       20`GP | FREE 14 (ДНЕЙ)
|   54 |            2 |           2 |            14 |          8 |    ДОЛЛ. |       20`GP | 
|   55 |            2 |           3 |           100 |         15 |    ДОЛЛ. |       20`GP | RELEASE
|   56 |           48 |           2 |             7 |          8 |    ДОЛЛ. |       20`GP | 
|   57 |           48 |           3 |            14 |         16 |    ДОЛЛ. |       20`GP | 
|   58 |           48 |           4 |           100 |         20 |     ГРН. |       20`GP | RELEASE
|   59 |           48 |           2 |             7 |         16 |    ДОЛЛ. |       40`GP | 
|   60 |           48 |           3 |            14 |         32 |    ДОЛЛ. |       40`GP | 
|   61 |           48 |           4 |           100 |         40 |    ДОЛЛ. |       40`GP | RELEASE
|   62 |            2 |           1 |            14 |          0 |    ДОЛЛ. |       40`GP | FREE 14 (ДНЕЙ)
|   63 |            2 |           2 |            14 |         15 |    ДОЛЛ. |       40`GP | 
|   64 |            2 |           3 |           100 |         30 |    ДОЛЛ. |       40`GP | RELEASE
После запуска EXECUTE PROCEDURE GET_DEMURRAGE(48,'20`GP',35); должно получиться:

Код: Выделить всё

| DEM_DAYSCOUNT | DEM_SALARY | 
|             7 |          0 |
|             7 |          8 |
|            14 |         16 |
|           100 |         20 |
и DEMURRAGE_MONEYS вернуть 420 ..!!


ПРОШУ ПОМОГИТЕ РАЗОБРАТЬСЯ В РАБОТЕ ПРОЦЕДУРЫ!
Последний раз редактировалось ERrorMAKros 15 сен 2007, 18:09, всего редактировалось 2 раза.

ERrorMAKros
Сообщения: 37
Зарегистрирован: 18 янв 2007, 01:05

Сообщение ERrorMAKros » 15 сен 2007, 18:01

Подскажите - почему после EXECUTE PROCEDURE TESTING или SELECT * FROM TESTING
переменаня SUMM ничему не равна?

Код: Выделить всё

 CREATE PROCEDURE TESTING
RETURNS("VARR_A" INTEGER, "SUMM" INTEGER)
     AS
  BEGIN
    FOR
 SELECT  IBLINE_AGENTS_DEMURRAGE."DEM_DAYSCOUNT" FROM IBLINE_AGENTS_DEMURRAGE
   INTO :VARR_A
      DO BEGIN SUMM=SUMM+VARR_A;
               END
               SUSPEND;
               ENd

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 15 сен 2007, 20:30

ERrorMAKros писал(а):Подскажите - почему после EXECUTE PROCEDURE TESTING или SELECT * FROM TESTING
переменаня SUMM ничему не равна?
Видимо потому что она не инициализирована.
А по умолчанию там null и в сумме с чем-то тоже дает null.
Кстати если есть какая либо переменная в for select на основе поля возможно содержащего null, то лучше использовать coalesce

ERrorMAKros
Сообщения: 37
Зарегистрирован: 18 янв 2007, 01:05

Сообщение ERrorMAKros » 15 сен 2007, 23:48

...Фсе, ...победил. Ох уж этот вашь Интербейz-ДрамЭнБэйз. Напоминает мне времена когда я программировал на ZX-Spectrum`е... +) +) +) Вот он рабочий скот:

Код: Выделить всё

 CREATE PROCEDURE GET_DEMURRAGE("LINECODE"         INTEGER   ,   /* флаг ID компании                   */
                                "CONTNUM"          VARCHAR(20) , /* тип контейнера [40`GP, 20`GP]      */
                                "DAYSPRESENT"      INTEGER)      /* общий промежуток дней              */
RETURNS                        ("DEMURRAGE_MONEYS" INTEGER)      /* результат подсчета                 */
     AS       DECLARE VARIABLE  "GET_DAYCOUNT"     INTEGER;      /* КОЛ-ВО  СУТОК                      */
              DECLARE VARIABLE  "GET_SALARY"       INTEGER;      /* КОЛ-ВО  ДЕНЕГ                      */
              DECLARE VARIABLE  "INC_DAYCOUNT"     INTEGER;      /* СЧЕТЧИК СУТОК                      */
              DECLARE VARIABLE  "INC_MONEYS"       INTEGER;      /* СЧЕТЧИК ДЕНЕГ                      */
              DECLARE VARIABLE  "CYCLE"            INTEGER;      /* ЦИКЛ                               */

  BEGIN    /* DAYSPRESENT     =DAYSPRESENT; */
              DEMURRAGE_MONEYS=000;
              GET_DAYCOUNT    =000;
              GET_SALARY      =000;
              INC_DAYCOUNT    =000;
              INC_MONEYS      =000;
              CYCLE           =000;
    FOR
 SELECT       IBLINE_AGENTS_DEMURRAGE."DEM_DAYSCOUNT",
              IBLINE_AGENTS_DEMURRAGE."DEM_SALARY"
   FROM       IBLINE_AGENTS_DEMURRAGE
  WHERE      (IBLINE_AGENTS_DEMURRAGE."DEM_LINECODE" =:LINECODE)
    AND      (IBLINE_AGENTS_DEMURRAGE."DEM_CONTNUM"  =:CONTNUM)
  ORDER  BY   IBLINE_AGENTS_DEMURRAGE."DEM_STEPINC"
   INTO      :GET_DAYCOUNT,
             :GET_SALARY
         DO   BEGIN 
              WHILE(CYCLE < GET_DAYCOUNT)
                 DO BEGIN
                 IF(DAYSPRESENT>INC_DAYCOUNT)
               THEN BEGIN INC_MONEYS      = INC_MONEYS  +GET_SALARY;
                          INC_DAYCOUNT    = INC_DAYCOUNT+001;
                          END /* IF..     */

                          CYCLE=CYCLE+001;
                          END /* WHILE... */

                          CYCLE           = 000;
                          GET_DAYCOUNT    = 000;
                          GET_SALARY      = 000;
                          END /* FOR...   */

                          DEMURRAGE_MONEYS= INC_MONEYS;
                          SUSPEND;
                          ENd

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 16 сен 2007, 13:50

Ох уж этот вашь Интербейz-ДрамЭнБэйз.
ох уж эти начинающие программисты, доку не читают, и все жалуются...

ERrorMAKros
Сообщения: 37
Зарегистрирован: 18 янв 2007, 01:05

Сообщение ERrorMAKros » 16 сен 2007, 17:29

Та ну, нина что я не жалуюсь ;) Все в порядке. Есть задача - нужно решить, ...а как я это буду делать - кроме меня никого не волнует. Очень тяжело писать программы на языке, которые понимаешь, но писать на нем еще не очень то хорошо можешь. Критика конечно нужна везде, мнений тоже столько же сколько и людей ...но руки мне отрывать не нужно, учите лучше меня пожалуйста! И что бы я без вас делал! Все же когда то начинали что то в первый раз!

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 17 сен 2007, 00:00

Учить - с удовольствием. Сначала отключи "ленивца" в IBE при редактировании процедур. А то у тебя имена переменных в двойных кавычках. Научись редактировать процедуры в SQL Editor.

Дальше. Вот это вот - порнография:

Код: Выделить всё

SELECT       IBLINE_AGENTS_DEMURRAGE."DEM_DAYSCOUNT",
              IBLINE_AGENTS_DEMURRAGE."DEM_SALARY"
   FROM       IBLINE_AGENTS_DEMURRAGE 
...
нельзя было алиас таблице IBLINE_... указать? Все стало бы намного проще:

Код: Выделить всё

SELECT       I.DEM_DAYSCOUNT, I.DEM_SALARY
   FROM       IBLINE_AGENTS_DEMURRAGE I
  WHERE      (I.DEM_LINECODE =:LINECODE)
    AND      (I.DEM_CONTNUM  =:CONTNUM)
  ORDER  BY   I.DEM_STEPINC

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 17 сен 2007, 11:01

DEMURRAGE_MONEYS=000;
Улыбнуло :)

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 17 сен 2007, 12:26

Многабукв читать недосуг, но должен отметить, что если дочитать что-нить про SQL до агрегатных функций, например SUM, то жизнь начнёт потихоньку налаживаться...

ERrorMAKros
Сообщения: 37
Зарегистрирован: 18 янв 2007, 01:05

Сообщение ERrorMAKros » 19 сен 2007, 00:13

Ну блин :lol: Чего все привязались к моей процедуре "SUMM=SUMM+VARR_A" ...агрегатные функции я знаю, тут дело не в них было, ...прямо вот простить мне не можете, ...эта процедура была приведена что бы вызвать ваше внимание на работу "...INTO :VARR_A". Вот лижбы кому то хохму на весь интернет раздуть, ...вот прямо диковинка какая - человек, который не знает interbase. Давайте меня на костре сожжем, ...а то все знают IB, а я вообще не от мира сего :lol:

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 19 сен 2007, 01:42

да никто тебя не ест. я вон, вообще, явные join-ы осознал только через лет 5 юзания IB по полной программе. До того было как-то без надобности, все неявными пользовался.
Если спрашиваешь, то будь готов к. У меня уже вторую неделю появляются свои вопросы, которые решаются как только я половину вопроса успеваю или спросить или мысленно сформулировать.
Последний раз редактировалось kdv 19 сен 2007, 22:38, всего редактировалось 1 раз.

Attid
Спец
Сообщения: 377
Зарегистрирован: 14 ноя 2006, 09:58

Сообщение Attid » 19 сен 2007, 21:31

интересная тема =)
даже никто не забил ногами, хотя гранату в руки можно было дать, типа результат сложить через процедуру в блоб и его одним махом вытащить на клиента :roll:

ERrorMAKros
Сообщения: 37
Зарегистрирован: 18 янв 2007, 01:05

Сообщение ERrorMAKros » 20 сен 2007, 09:58

2Attid: Я в начале тоже об этом подумал. Вроде мысль ничего так =)

2kdv: Join`ы меня, в прошлом году, очень выручили. Задание было написать "универсальный поиск" для одной из баз данных, ...что бы можно было найти иголку в стогу сена =)

Ответить