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

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

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

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

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

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

[Interbase (v6.00) / Borland Delphi v6.00]
Доброго времени суток!
Нужна помощь в решении создавшейся задачи.
Есть результат запроса:

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

IBemployee

------+---------
 Days |  Moneys
------+---------
   4  |    22
   8  |    11
  12  |     5 
  18  |    12
   9  |     7
   3  |     1
…соответственно таблица, в результате, может имеет разное кол-во строк, Загадка в том, что – как организовать возможность возвращения
данных в этом же порядке со стороны сервера в переменную? Возможно ли средствами хранимых процедур реализовать результат процедуры в
виде двумерного динамического массива, возможны ли двумерные динамические массивы в языке interbase? Или подскажите пожалуйста свои предложения/решения.

Спасибо.

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

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

1. не вижу "порядка" в данных.
2. что значит "со стороны сервера в переменную"? Вы же прочитали данные, ну и кладите их куда угодно.
3. вам уже сервер возвращает МАССИВ. что вы хотите с ним делать на сервере?
4. динамические массивы в языке IB/FB не поддерживаются

напомню также, что InterBase 6.0 настоятельно НЕ рекомендуется к использованию. как минимум потому, что ему уже 7 лет.

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

Сообщение ERrorMAKros » 12 сен 2007, 13:10

kdv спасибо за советы, как всегда выручаете!

01. Правила порядка задаются в select запросе. В приведенном мной примере таблицы порядок будет сверху-вниз =)

02. Со стороны серевера это больше вопрос на тему, ...можно ли вернуть результат отбора - не в виде таблицы, ...и лучше ли это вообще!? Потому как данный результат отбора это часть хранимой процедуры. т.е. процедурой идет отбор по условиям, получаем такого вот рода таблицу, а потом данные из этой таблицы подтвергаются всевозможным математическим вычеслениям (в коде программы клиента (соответственно это удобней делать в готовых массивах/переменных)).

03. Мне нужно передать этот массив в компактном и удобном виде с серва к клиенту для дальнейших вычеслений.

04. Жаль. А что посоветуете?

Очень не хочется считывать результаты таблицы с клиентской части, путем перехода от первой строки результата к последней, это же не по взрослому. Но пока что другого варианта не вижу. Может как то можно "цуликом захватить" результаты и в компактном виде передать клиенту?!

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

Сообщение Merlin » 12 сен 2007, 13:18

Ты не поверишь, но в конпутере вся информация живёт и ползает в конце концов побитно :roll:

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

Сообщение ERrorMAKros » 12 сен 2007, 13:29

2 Merlin: Супер! Очень информативно!

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

Сообщение kdv » 12 сен 2007, 13:57

приведенном мной примере таблицы порядок будет сверху-вниз
порядок есть только у отсортированного множества записей (по order by). если в запросе order by есть, записи будут именно так и отсортированы.
а потом данные из этой таблицы подтвергаются всевозможным математическим вычеслениям (в коде программы клиента (соответственно это удобней делать в готовых массивах/переменных)).
не вижу проблем. получил на клиента набор данных, вычисляй что угодно.
Мне нужно передать этот массив в компактном и удобном виде с серва к клиенту для дальнейших вычеслений.
он и так передается в компактном и удобном виде.
Жаль. А что посоветуете?
контекст вопросов не дают возможности ответить более конкретно.
у меня вообще по прочтении вопросов возникло ощущение, что это шутка.

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

Сообщение ERrorMAKros » 12 сен 2007, 16:07

В запросе есть order by =) ...с запросом все впорядке =) ...проблема в том, что я вынужден прибегнуть к такого вот плана коду в клиентской части программы:

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

  type Cont_
    of Record SaveDays  : INTeger;
              SaveMoneys: INTeger;
              end;
   var IB_array_: Array of Cont_;
 begin SetLength(IB_array_,IB_query_IBtable_.RecordCount);
                           IB_query_IBtable_.First; 
repeat IB_array_[IB_query_IBtable_.RecNo].SaveDays  :=IB_query_IBtable_Days  .AsInteger;
       IB_array_[IB_query_IBtable_.RecNo].SaveMoneys:=IB_query_IBtable_Moneys.AsInteger;
       IB_query_IBtable_.Next;
 until IB_query_IBtable_.Eof;
       end; 
...я подумываю что это простой и надежный способ, ...но ...детский. Это касательно программного кода для языка, на котором пишется клиентская часть; Есть ли возможность реализовать что то подобное в виде хранимой процедуры InterBase.

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

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

Сообщение kdv » 12 сен 2007, 16:21

простой и нормальный код, за исключением совершенно излишнего использования IBTable. хотя сойдет и так.

тебе надо что-нибудь повычурнее, замудреннее, чтобы в голове загудело?
Есть ли возможность реализовать что то подобное в виде хранимой процедуры InterBase.
что именно реализовать? перебрать записи? для этого в процедурах есть for select.
подскажите пожалуйста правильное решение
я до сих пор не понимаю вопроса.

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

Сообщение ERrorMAKros » 12 сен 2007, 17:01

IBtable... у меня на самом деле TIBquery =)
...собственно сомнения именно в правильности метода - "перебора записей" с клиентской стороны. Хочется что бы как можно больше работы выполнял именно сервер. Уже реализованны хранимые процедуры добавления, замены, удаления нужных строк и записей. Так требует тех задание.

С клиентской стороны я могу получить значения в массив практически любого кол-ва полученных строк, ...и далее делать все что мне не обходимо.

А в серверной стороне могу читать так же почти все строки, но только если изначально const`антирую макс. длину массива в переменной хранимой процедуры.

Возможна ли такая хитрость, ...можно ли в хранимой процедуре объявить длину array переменной - длиной размером в кол-во ранее полученных срок?


Т.Е.

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

IBemployee

  ------+---------
   Days |  Moneys
  ------+---------
0.   4  |    22
1.   8  |    11
2.  12  |     5
3.  18  |    12
4.   9  |     7
5.   3  |     1
...после выборки select ... from IBemployee... мы получаем 5 записей.

а далее объявить:

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


CREATE PROCEDURE SET_ARRAY(RECORDS_COUNT INTEGER)  
RETURNS (DECLARE VARIABLE MYArray_ INTEGER[2,RECORDS_COUNT])
....?? ...что позволит в ХП создать двумерный массив длинной в 5 полученных записей, и через цикл записать в него нужные данные, ...и передать переменную в клиентскую часть.
Последний раз редактировалось ERrorMAKros 12 сен 2007, 17:48, всего редактировалось 3 раза.

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

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

ERrorMAKros писал(а): С клиентской стороны я могу получить значения в массив практически любого кол-ва полученных строк, ...и далее делать все что мне не обходимо.
Во-первых, не надо торопиться. В следующем семестре будут читать работу со списками. Частным случаем которого является концепция датасета. Unidrectional - однонаправленного, Bi- двунаправленного.
Во-вторых, слова "c клиентской стороны ... массив практически любого кол-ва строк" давно уже у большинства вызывают ироническую усмешку.

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

Сообщение ERrorMAKros » 12 сен 2007, 17:27

2 Merlin: ...создается впечатление что ты форумный "Бот". Шуточки в разделе "пятница".

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

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

ERrorMAKros писал(а):2 Merlin: ...создается впечатление что ты форумный "Бот".
А мне пофиг.
ERrorMAKros писал(а): Шуточки в разделе "пятница".
Ни малейшего намёка на шутки. Тебе просто проздрачно намекают, что жизнь сложнее привычной протоптанной тропки и что каждый инструмент даёт наилучший эффект если его применяют по назначению, а не как привычно применять другой.

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

Сообщение ERrorMAKros » 12 сен 2007, 17:40

2 Merlin: Если начал отвечать - видимо не пофиг. Спасибо за участие в топике, но я создал его для того, что бы выяснить у профессионалов какие нибудь др. особенности. Мне нужно с вами посоветоваться касательно тематики задания. Я пытаюсь выяснить - существуют ли более продуктивные или стабильные решения задачи! Interbase серьезный комплекс и всех прелестей работы с ним вот так вот сразу мне не объять. Поэтому и прошу помощи у знающих людей.

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

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

ERrorMAKros писал(а):2 Merlin: Если начал отвечать - видимо не пофиг.
Смотря что. Какое у кого относительно меня впечатление - абсолютно пофиг.
ERrorMAKros писал(а): Interbase серьезный комплекс и всех прелестей работы с ним вот так вот сразу мне не объять. Поэтому и прошу помощи у знающих людей.
Понимаешь какая штука. Организация данных в виде массивов в общем и целом предназначена для тех задач, в которых требуется доступ в одном выражении к нескольким (однотипным) элементам этого массива по индексу (номеру). Записи же резалтсетов, возвращаемых запросами к СУБД, как правило, самодостаточны и доступ к ним осуществляется по индексу(ключу) или search/locate condition по набору атрибутов, порядок следования для линейного перебора тоже задаётся запросом. Такой шаг, как тупое копирование резалтсета в массив наводит на размышления о неполадках в консерватории сразу, человек явно идёт не в ту сторону. Построение, скажем кросстаба из полученного резалтсета вызывала бы меньшее удивление, да и то не в массиве, а в специализированном датасете типа in-memory-table. Чтобы воспользоваться на нём стандартными для работы с множествами методами.

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

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

собственно сомнения именно в правильности метода - "перебора записей" с клиентской стороны
код примерно правильный. других неправильностей не вижу.
Хочется что бы как можно больше работы выполнял именно сервер.
смотря какой работы. если работу excel, то сервер для этого не предназначен.
Возможна ли такая хитрость, ...можно ли в хранимой процедуре объявить длину array переменной - длиной размером в кол-во ранее полученных срок?
да нет в языке IB/FB никаких переменных-массивов ни в процедурах ни вообще.
....?? ...что позволит в ХП создать двумерный массив длинной в 5 полученных записей, и через цикл записать в него нужные данные, ...и передать переменную в клиентскую часть.
натуральные бредни. знаешь, есть такая поговорка - "неудобно ходить по большому в почтовый ящик". это примерно и есть то, что ты мудришь с этим массивом.
Я пытаюсь выяснить - существуют ли более продуктивные или стабильные решения задачи!
продуктивно - это когда запрос выполняется быстро, а не когда хитрозавернутым способом записи конвертируются в какой-то массив а потом аналогично завернуто транслируются клиенту.

Объясняю, почему твое желание бредовое:
- сервер все равно динамически или целиком строит СВОЙ массив записей, который передается клиенту
- количество записей может быть разным

Если сервер будет сначала выбирать записи, потом создавать у себя массив, потом передавать его тебе, а ты потом все равно будешь брать этот массив и аллокировать в программе (ведь сервер и клиент обычно находятся на разных компьютерах, не так-ли? даже если бы и на одном), то получается совершенно лишнее аллокирование массива фиг знает какого размера на сервере.

я тебе больше скажу, у тебя и так происходит двойное аллокирование в приложении, потому что датасеты, и в т.ч. IBTable (при обычном next), при перемещении по записям аллокируют их динамически в своем буфере. Исключение - компонент IBSQL. Которым обычно пользуются если надо обработать много записей.

Кстати, ты не сказал, зачем ты вообще строишь этот массив. Т.е. тот массив, в который помещаешь значения из датасета. Дальше что с ним будет? Почему нельзя сразу обработать записи, получая их по DataSet.Next ?
Interbase серьезный комплекс и всех прелестей работы с ним вот так вот сразу мне не объять.
пока у тебя проблемы скорее всего в алгоритмике.

Кстати, еще раз насчет IB 6.0 - я с трудом удерживаюсь чтобы не перестать отвечать и вообще закрыть этот топик именно по причине IB 6.0. Потому что пока не увидел от тебя обоснования его использования.

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

Сообщение ERrorMAKros » 12 сен 2007, 18:25

Спасибо, все понятно. Interbase 6 - ...не я его захотел =) А насчет данных, ...данные в дальнейшем будут учавстовать в разных формулах. Если говорить прямо, то суть данных в таблице это:

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

IBemployee

  ------+---------
   Days |  Moneys
  ------+---------
0.   4  |    22       - оплата за 1 день (на протяжении первых      4 дней) по 22$
1.   8  |    11       - оплата за 1 день (на протяжении следующих   8 дней) по 11$
2.  12  |     5       - оплата за 1 день (на протяжении следующих  12 дней) по  5$
3.  18  |    12       - оплата за 1 день (на протяжении следующих  18 дней) по 12$ 
4.   9  |     7       - оплата за 1 день (на протяжении следующих   9 дней) по  7$  
5.   3  |     1       - оплата за 1 день (на протяжении следующих   3 дней) по  1$  

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

Сообщение WildSery » 12 сен 2007, 19:09

ERrorMAKros писал(а):Interbase 6 - ...не я его захотел =)
Преподаватель? Давай его сюда, мозги ему освежим.
ERrorMAKros писал(а):А насчет данных, ...данные в дальнейшем будут учавстовать в разных формулах. Если говорить прямо, то суть данных в таблице это:
Хрен с ней, с сутью.
От тебя хотим получить ответ, какие именно "разные формулы" будут применяться, с целью понимания, а нужен ли тебе вообще массив.

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

Сообщение Merlin » 12 сен 2007, 19:38

Кстати, только сейчас обратил внимание, в котором из форумов сидим с массивами-то. Не хочу намекать на систематические личностные особенности логического выбора решений ни разу, так, к слову пришлось :wink:

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

Сообщение kdv » 12 сен 2007, 19:43

не я его захотел
а кто? может, тогда "он" захочет, чтобы ты писал под ДОС?
Если говорить прямо, то суть данных в таблице это:
ну и что? зачем тут массив-то?
Merlin писал(а):в котором из форумов сидим с массивами-то
я вижу, тоже был озадачен

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

Сообщение ERrorMAKros » 12 сен 2007, 22:26

Какая разница какие формулы потом будут применяться?! Не вижу разници в каком IB или FB это сделать, потому как все остановились только на методе "перебора" полученных данных. Захотят что бы писал под MS-DOS, ...придется писать (TurboVision, GraphVision еще не удалил) :-D

Суть в том, что мне нужно как можно быстрее результаты из Interbase таблицы передать в переменные Delphi, что бы потом проводить над ними всевозможные вычислительные операции: умнажение одно на другое, деление, сложение, вычитание и т.п. Если результат таблицы выдаст 1000 записей, придется делать progressbar и пользователь будет "втыкать" в монитор пока процес не пройдет от первой и до последней 1000`ной записи. Вот я и ищу способ, что бы не перебирать по одной записи, а получить от сервера результат в удобном мне виде (самое подходящее это в динамическом массиве) и все сразу целиком. Что бы в "клиенте" я вызвал процедуру через TIBStoredProc и она вернула мне результат через "TIBStoredProc.Params.ParamByName('result')....". Что то типа старого TBatchMove только не из таблицы в таблицу, а из таблицы в переменную.

Уже было сказано что IB сервер не умеет создавать в себе динамические массивы, это меня и расстроило. Это говорит о том, что можно создать в ХП свою myarray переменную длинной в maxlength и резултаты выборки передавать в нее, что после своей работы вернет клиенту уже готовый набор данных, за один запрос.

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

CREATE PROCEDURE SET_ARRAY (some_params INTEGER)
RETURNS (myarray INTEGER[maxlength])
А если кол-во результатов будет maxlength+001, ...мой массив myarray при чтении результатов в себя - треснет по швам.....!! Это мне и не подходит.

Данные которые я пытаюсь прочитать из таблицы - представляют из себя условия для финансовых мат. операций, поэтому нужны все строки результатов без исключения.

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

IBemployee

  ------+---------
   Days |  Moneys
  ------+---------
0.   4  |    22       - оплата за 1 день (на протяжении первых      4 дней) по 22$
1.   8  |    11       - оплата за 1 день (на протяжении следующих   8 дней) по 11$
2.  12  |     5       - оплата за 1 день (на протяжении следующих  12 дней) по  5$
3.  18  |    12       - оплата за 1 день (на протяжении следующих  18 дней) по 12$
4.   9  |     7       - оплата за 1 день (на протяжении следующих   9 дней) по  7$ 
5.   3  |     1       - оплата за 1 день (на протяжении следующих   3 дней) по  1$ 

Ответить