Страница 2 из 2

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

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

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

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

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

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

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

Добавлено: 15 сен 2007, 16:14
ERrorMAKros
Люди , помогите пожалуйста разобраться в процедуре , ...т.к. только у вас смогу спросить многие мелочи и сложновато перестроиться на др. синтаксис языка после 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 ..!!


ПРОШУ ПОМОГИТЕ РАЗОБРАТЬСЯ В РАБОТЕ ПРОЦЕДУРЫ!

Добавлено: 15 сен 2007, 18:01
ERrorMAKros
Подскажите - почему после 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

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

Добавлено: 15 сен 2007, 23:48
ERrorMAKros
...Фсе, ...победил. Ох уж этот вашь Интербей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

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

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

Добавлено: 17 сен 2007, 00:00
kdv
Учить - с удовольствием. Сначала отключи "ленивца" в 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

Добавлено: 17 сен 2007, 11:01
WildSery
DEMURRAGE_MONEYS=000;
Улыбнуло :)

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

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

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

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

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

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