Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.09.23;
Скачать: CL | DM;

Вниз

Объект по работе с cross-таблицей   Найти похожие ветки 

 
DelphiLexx ©   (2007-03-21 15:20) [0]

Возникла следующая проблема:
Есть таблица Q_DICT со следующей структорой:
QM_ID QM_NAME DESCRIPTION
см рис pic1.
Есть таблица R_DICT (аналог Q_DICT)
R_ID R_NAME DESCRIPTION
см рис pic2

Есть Таблица RQ_DICT состоящая из данных Q_DICT и R_DICT
R_ID Q_ID RQ_VALUE
где R_ID, Q_ID внешние ключи на ID - полей на таблицы на Q_DICT R_DICT
см рис pic3

Нужен объект которому бы я передавал список R_ID, QM_ID и он бы мне возвращал скажем TRxMemoryData следующей структуры
см рис pic_4

http://www.rsdn.ru:80/File/26841/pic_itog.JPG


 
Jan   (2007-03-21 15:48) [1]

тебе это нужно для отчета? Если да, то например, в FastReport есть спец. копонент, торый тебе построит как надо., если нет, то какая субд?


 
DelphiLexx ©   (2007-03-21 15:50) [2]


> тебе это нужно для отчета? Если да, то например, в FastReport
> есть спец. копонент, торый тебе построит как надо., если
> нет, то какая субд?

Нет. Субд у меня FireBird2.0


 
Jan   (2007-03-21 15:51) [3]


> Нет. Субд у меня FireBird2.0
>

что ты дальше будешь делать?


 
DelphiLexx ©   (2007-03-21 15:55) [4]


> что ты дальше будешь делать?

В смысле. Я тебя что то не совсем понимаю


 
Jan   (2007-03-21 15:57) [5]


> В смысле. Я тебя что то не совсем понимаю

ну допустим ты получил эти значения, что дальше?


 
DelphiLexx ©   (2007-03-21 16:04) [6]


> ну допустим ты получил эти значения, что дальше?

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


 
Jan   (2007-03-21 16:12) [7]

исщи Pivot Table - есть отдельные компоненты, можно через COM из MS Office заюзать. Все они принимают нормальные нормированные данные.


 
Jan   (2007-03-21 16:16) [8]

хотя может тебе и этого хватит
http://delphikingdom.ru/asp/viewitem.asp?catalogid=529


 
PEAKTOP ©   (2007-03-21 16:24) [9]

Формируй набор данных через динамическую хранимую процедуру EXECUTE BLOCK, а само тело процедуры (и заодно отчет, ну там метки раскидывай по бэндам) формируй программно в цикле по справочнику, по которому хочешь "развернуть горизонтально".
Только на IBX забей сразу с этими приколами. Воcпользуйся FIBPlus.


 
DelphiLexx ©   (2007-03-21 16:24) [10]


> http://delphikingdom.ru/asp/viewitem.asp?catalogid=529

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

Что касается Pivot таблиц, по-моему, немного не то.


 
DelphiLexx ©   (2007-03-21 16:27) [11]


> Формируй набор данных через динамическую хранимую процедуру
> EXECUTE BLOCK, а само тело процедуры (и заодно отчет, ну
> там метки раскидывай по бэндам) формируй программно в цикле
> по справочнику, по которому хочешь "развернуть горизонтально".
>  


EXECUTE BLOCK - а как этой процедурой пользоваться. И разве такое возможно, чтобы часть хранимой процедуры была в БД Firebird, а часть в проекте.
Не мог бы напримере рассказать как это делается.


 
Jan   (2007-03-21 16:29) [12]


> Формируй набор данных через динамическую хранимую процедуру
> EXECUTE BLOCK, а само тело процедуры (и заодно отчет, ну
> там метки раскидывай по бэндам) формируй программно в цикле
> по справочнику, по которому хочешь "развернуть горизонтально".
>
> Только на IBX забей сразу с этими приколами. Воcпользуйся
> FIBPlus.

только ты сначала расскажи как вернуть динамическое кол-во столбцов, а потом рекомендуй...


> Что касается Pivot таблиц, по-моему, немного не то.

как раз-то. тебе нужен OLAP.


 
DelphiLexx ©   (2007-03-21 16:40) [13]


> тебе нужен OLAP.

что такое OLAP


 
Jeer ©   (2007-03-21 16:50) [14]

Ищи по ключ.словам: cross-таблица, перекрестная таблица, шахматка.

Для примера можно ее делать так:

CREATE TABLE Pivot
( Year      SMALLINT,
 Quarter   TINYINT,
 Amount      DECIMAL(2,1) )

SELECT Year,
   SUM(CASE Quarter WHEN 1 THEN Amount ELSE 0 END) AS Q1,
   SUM(CASE Quarter WHEN 2 THEN Amount ELSE 0 END) AS Q2,
   SUM(CASE Quarter WHEN 3 THEN Amount ELSE 0 END) AS Q3,
   SUM(CASE Quarter WHEN 4 THEN Amount ELSE 0 END) AS Q4
FROM Pivot
GROUP BY Year


 
PEAKTOP ©   (2007-03-21 17:52) [15]


> только ты сначала расскажи как вернуть динамическое кол-во столбцов, а потом рекомендуй...

Этап первый - пробуем:
1) Читаем какую-нить книжку по созданию хранимых процедур в InterBase/FireBird.
2) Пишем хранимую процедуру (для сферического коня в вакууме).
3) Заменяем в ней "CREATE PROCEDURE PROC_NAME" на "EXECUTE BLOCK".
4) Засовываем в свойство TIBQuery.SQL.Text :=  полученный скрипт.

Этап второй - усложняем (на примере автора топика, если позволите):
Допустим, у нас на форме Form1 лежит dbg:TDBGridEh, изображенный на PICT_4 для него набор данных qr:TIBQuery; (Свойство ParamCheck = false - это важно для IBX !!!)
Также есть IBQuery1 :TIBQuery вспомагательный

procedure TForm1.Button1Click(Sender :TObject);
var
 lk_Vars, lk_Body, lk_SQL :string;
 lk_Col :TColumnEh;
 i :Integer;
begin
 if IBQuery1.Active then IBQuery1.Close;
 
 dbg.Columns.Clear;
 lk_Col := dbg.Columns.Add;
 lk_col.FieldName := "R_NAME";
 lk_Col.Title.Caption := "R_NAME";
 .... и т.д. выставляем свой-ва первой колонки.

 IBQuery1.SQL.Text := "SELECT * FROM Q_DICT ORDER BY QM_ID ";
 IBQuery1.Open;
 IBQuery1.First;
 lk_vars := "";
 lk_body := "";
 i := 0;
 while not IBQuery1.EOF do
   begin
   lk_Vars := lk_Vars +#13#10+"  ,FLD"+IntToStr(i)+" NUMERIC(15,2) ";
   lk_body := lk_body +#13#10+"    SELECT FIRST 1 T.RQ_VALUE FROM RQ_DICT T WHERE (T.R_ID = :R_ID) and (T.Q_ID = """+IBQuery1.FieldByName("QM_ID").AsString+""") INTO :FLD"+IntToStr(i)+"; ";

   lk_Col := dbg.Columns.Add;
   lk_col.FieldName := "FLD"+IntToStr(i);
   lk_Col.Title.Caption := IBQuery1.FieldByName("QM_NAME").AsString;
 .... и т.д. выставляем свой-ва колонки.

   i := i + 1;
   IBQuery1.Next;
   end;

 if qr.Active then qr.Close;
 qr.SQL.Text :=
   "EXECUTE BLOCK RETURNS ( "+#13#10+
   "   R_ID INTEGER "+#13#10+
   "  ,R_NAME VARCHAR(50) "+#13#10+
   lk_vars+#13#10+
   ") AS "+#13#10+
   "BEGIN "+#13#10+
   "  FOR SELECT TB.R_ID, TB.R_NAME FROM R_DICT TB INTO :R_ID, :R_NAME DO "+#13#10+
   "  BEGIN "+#13#10+
   lk_body+#13#10+
   "  SUSPEND; "+#13#10+
   "  END"+#13#10+
   "END ";
end;


 
PEAKTOP ©   (2007-03-21 18:03) [16]


> Jeer ©   (21.03.07 16:50) [14]
>
> Для примера можно ее делать так:


Хм, неплохая идея ! спасибо.


 
Jan   (2007-03-21 18:57) [17]


> PEAKTOP ©   (21.03.07 17:52) [15]

по коду не будем - Вам бы почитать вообще о программировании.
а в общем, зачем изобретать велик - если уже все сделали за нас? только поискать...


 
Jan   (2007-03-21 19:00) [18]

хотя бы это
http://pivotcube.com/cgi-bin/index.cgi?page=products


 
PEAKTOP ©   (2007-03-21 19:22) [19]


> по коду не будем - Вам бы почитать вообще о программировании.


Не поверишь, каждый день читаю и при этом черпаю что-то новое. Однако при этом болезненное самомнение как-то не развивается, а скроее наоборот.


> а в общем, зачем изобретать велик - если уже все сделали за нас? только поискать...

 Программирование со времен фон Неймана - сплошное изобретание велика.

> хотя бы это
> http://pivotcube.com/cgi-bin/index.cgi?page=products

Помогаем сайту зарабатывать кровные 395$ ? :))


 
DelphiLexx ©   (2007-03-21 20:21) [20]


> Этап первый - пробуем:
> 1) Читаем какую-нить книжку по созданию хранимых процедур
> в InterBase/FireBird

Я использую компоненты FIBPlus"a написал В DataSet.Seletct.Sql готовый execute block. Проверил его в IBExpert"e замечательно работает, но когда начинаю его выполнять из программы выдается ошибка

Token unknown line 1 column 248
?.

Это как раз место где между R_DICT TB INTO и :R_ID


 
Jan   (2007-03-22 09:34) [21]


> Помогаем сайту зарабатывать кровные 395$ ? :))

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


>
> Это как раз место где между R_DICT TB INTO и :R_ID

символ : не начто не наводит? Ты бы почитал чтоли хелп, прежде чем юзать компоненты...


 
PEAKTOP ©   (2007-03-22 09:38) [22]


> Это как раз место где между R_DICT TB INTO и :R_ID

FIBPlus досконально не знаю (так, кодил пару раз), потому как пользую самописную библиотеку доступа, основанную на исходниках IBX. Но в любом случае, копать тебе нужно в сторону проверки параметров перед выполнением запроса. В IBX это свойство TIBQuery.ParamCheck :Boolean, его нужно поставить в false, чтобы парсер не проверял параметры перед выполнением запроса.

Проблема заключается в том, что "двоеточие" и "вопросительный знак" в компонентах Delphi зарезервировано под параметры, а в Procedure SQL двоеточие тоже зарезервировано под передачу значений в параметры хранимой процедуры, поэтому парсер "путается" перед выполнением запроса не отличая, где параметры, а где передача значений. Как сказано в фирменной документации ($firebird/doc/sql.extensions/README.execute_block.txt)

....................
The client should preprocess only head of the SQL statement or use "?"
instead of ":" as parameter indicator because in a body of the block may be links
to local variables and \ or parameters with a colon ahead.
...........................
(c) Vlad Horsun <horsun@kdb.dp.ua>

Я проблему решил тем, что перекрыл в исходниках те места, где парсится SQL, оставив для передачи параметров только "вопросительный знак" и убил "двоеточие".
В твоем случае можно попробовать следующее.
Компонент T..DataSet из набора FIBPlus имеет пять скрытых компонентов TSQL, свойства SQL которых вынесены в published как SelectSQL, InsertSQL, DeleteSQL и т.д. Тебе нужно найти компонент ( T..DataSet.FindComponent("CompName") ), который SelectSQL и перед выполнением запроса поставить в нем свойство ParamCheck = false.


 
PEAKTOP ©   (2007-03-22 09:49) [23]


> я давно такого не читал где бы весь код был в коде нажатия кнопки...

Для тебя это так принципиально ? :))
Код, приведенный выше - изложение самой идеи и написан для примера. Причем, он не работоспособный на 100%, там есть несколько ошибок. Если у автора топика получилось выполнить полученный в результате запрос в IBExpert-e, то значит он нашел эти ошибки и исправил.
Как ни странно, ты на них не указал, кроме принципиальных кнопок.


 
Jan   (2007-03-22 09:57) [24]


> Для тебя это так принципиально ? :))

чистота кода - это тоже хороший совет, не находишь?


> Причем, он не работоспособный на 100%, там есть несколько
> ошибок.

т.е. ты предлагаешь его мне копировать себе и разбираться - увольте. автору надо - пусть поломает голову.


 
DelphiLexx ©   (2007-03-27 17:24) [25]


> SelectSQL и перед выполнением запроса поставить в нем свойство
> ParamCheck = false.

тогда переменные Returns понимаются, а передаваемые параметры после ParamCheck := false не понимаются. Если сделать так ParamCheck := true, то становиться все наоборот.


 
gizfi   (2007-05-19 09:16) [26]

<a href=  ></a>   [url=][/url]


 
zklxm   (2007-05-19 18:47) [27]

<a href=  ></a>   [url=][/url]


 
DelphiLexx ©   (2007-05-21 16:56) [28]


> <a href=  ></a>   [url=][/url]

Что это за бред.



Страницы: 1 вся ветка

Текущий архив: 2007.09.23;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.028 c
2-1188367095
Человек
2007-08-29 09:58
2007.09.23
Запаковать надо файл


15-1187794005
lookin
2007-08-22 18:46
2007.09.23
MAC-адрес сетевой карты


2-1188365803
Алик
2007-08-29 09:36
2007.09.23
Как сделать окно главным относительно других?


15-1187760531
SerJaNT
2007-08-22 09:28
2007.09.23
Ubuntu 7.04 Live CD


2-1188305625
Shad
2007-08-28 16:53
2007.09.23
Работа с другими программами