Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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


Страницы:   1 2

DelphiLexx ©   (2007-03-21 15:20:00) 

Возникла следующая проблема:
Есть таблица 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


DelphiLexx   (2007-05-21 16:56:00) [1]


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

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


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

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


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

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


DelphiLexx   (2007-03-27 17:24:00) [4]


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

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


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


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

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


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

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


PEAKTOP   (2007-03-22 09:49:00) [6]


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

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


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


> Это как раз место где между 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.


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


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

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


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

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


DelphiLexx   (2007-03-21 20:21:00) [9]


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

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

Token unknown line 1 column 248
?.

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


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


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


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


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

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

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

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


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

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


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


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

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


PEAKTOP   (2007-03-21 18:03:00) [13]


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


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


PEAKTOP   (2007-03-21 17:52:00) [14]


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

Этап первый - пробуем:
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;


Jeer   (2007-03-21 16:50:00) [15]

Ищи по ключ.словам: 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


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


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

что такое OLAP


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


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

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


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

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


DelphiLexx   (2007-03-21 16:27:00) [18]


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


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


DelphiLexx   (2007-03-21 16:24:00) [19]


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

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

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


PEAKTOP   (2007-03-21 16:24:00) [20]

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо