Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2007.09.23;
Скачать: [xml.tar.bz2];

Вниз

Объект по работе с 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.038 c
15-1186752698
_Mike_
2007-08-10 17:31
2007.09.23
Про компилятор


6-1170081738
ildarkh
2007-01-29 17:42
2007.09.23
TIDTCPServer(+SSL Intercept) внутри DLLки


1-1184246064
Unknown user
2007-07-12 17:14
2007.09.23
Помогите с матстатистикой


15-1187724746
Rouse_
2007-08-21 23:32
2007.09.23
Возвращение к истокам


15-1188044874
Бася
2007-08-25 16:27
2007.09.23
Эксперт для Делфи





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский