Пакетные запросы

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Пакетные запросы

Сообщение bogdan » 11.01.2016 21:20:40

Здравствуйте. Вы не подскажите как в Lazarus с помощью TSQLQuery или другим компонентом можно сделать пакетный запрос. Например мне сначала надо сделать выборку по одной таблице, а уже результаты выборки будут использоваться в другом запросе?
bogdan
новенький
 
Сообщения: 40
Зарегистрирован: 20.05.2015 21:32:49

Re: Пакетные запросы

Сообщение Снег Север » 11.01.2016 21:37:49

Это не к Lazarus и его компонентам вопрос должен быть, а к серверу базы данных. Как вы средствами конкретной базы свои потребности реализуете. А компоненты только передают запросы серверу и получают от него результаты.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3053
Зарегистрирован: 27.11.2007 16:14:47

Re: Пакетные запросы

Сообщение bogdan » 12.01.2016 00:42:57

Ну например мне нужно сделать зарос
Select * From Table1
и потом уже результат этого запроса, например пусть он будет Table1Tmp
выполнить в другом запросе
Select * from Table2 Left Join Table1Tmp.Id = Table2.id

Как это можно реализовать в Лазарусе?
bogdan
новенький
 
Сообщения: 40
Зарегистрирован: 20.05.2015 21:32:49

Re: Пакетные запросы

Сообщение Padre_Mortius » 12.01.2016 00:51:51

Код: Выделить всё
select * from Table2 t2 left join Table1 t1 on t1.Id=t2.Id

Вроде как-то так
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Re: Пакетные запросы

Сообщение Снег Север » 12.01.2016 09:28:50

bogdan писал(а):Как это можно реализовать в Лазарусе?

Повторяю, это реализуется НЕ в лазарусе, а НА СЕРВЕРЕ. Вы не сообщаете, с каким сервером баз данных вы намерены работать. Но большинство распространенных поддерживают создание временных таблиц и встроенных функций. Вот этими средствами ваша задача и решается. Как создавать такие таблицы и функции смотрите в описании языка SQL соответствующего сервера.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3053
Зарегистрирован: 27.11.2007 16:14:47

Re: Пакетные запросы

Сообщение resident » 12.01.2016 12:11:57

bogdan писал(а):Например мне сначала надо сделать выборку по одной таблице, а уже результаты выборки будут использоваться в другом запросе?

Это уже к Паскалю не относится, тут чисто язык SQL сервера

bogdan писал(а):Вы не подскажите как в Lazarus с помощью TSQLQuery или другим компонентом можно сделать пакетный запрос.

Как сделать пакетный и любой иной SQL запрос на сервер можно узнать, прочитав статьи на этом сайте (не на форуме) о базах данных
http://freepascal.ru/article/lazarus/20090416150500/
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Пакетные запросы

Сообщение DYUMON » 12.01.2016 15:11:08

почитай про синтаксис sql сначало. про представления, обьединения и прочее.
Аватара пользователя
DYUMON
постоялец
 
Сообщения: 234
Зарегистрирован: 11.03.2009 13:32:54

Re: Пакетные запросы

Сообщение WAYFARER » 13.01.2016 12:09:57

bogdan писал(а):надо сделать выборку по одной таблице, а уже результаты выборки будут использоваться в другом запросе?

Например так.
Код: Выделить всё
select * from table2 t2 where t2.id in (select id from table1)
Аватара пользователя
WAYFARER
энтузиаст
 
Сообщения: 537
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Re: Пакетные запросы

Сообщение Снег Север » 13.01.2016 16:03:52

Если что-то достаточно сложное, то можно использовать временные таблицы. Вот как я делал в одной программе (mysql):
Код: Выделить всё
CREATE TEMPORARY TABLE IF NOT EXISTS tmpuserscall ...
//описание таблицы
... ENGINE=HEAP;
TRUNCATE tmpuserscall;
INSERT INTO tmpuserscall SELECT ...
//заполняем таблицу
SELECT ...
FROM tmpuserscall, ...

В mysql временная таблица существует в пределах одной сессии и автоматически уничтожается при дисконнекте.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3053
Зарегистрирован: 27.11.2007 16:14:47

Re: Пакетные запросы

Сообщение sign » 14.01.2016 07:32:37

bogdan писал(а):Здравствуйте. Вы не подскажите как в Lazarus с помощью TSQLQuery или другим компонентом можно сделать пакетный запрос. Например мне сначала надо сделать выборку по одной таблице, а уже результаты выборки будут использоваться в другом запросе?

Можно и вот так:
Это в программе:
Код: Выделить всё
var qList: TSQLQuery;
...
    qList.SQL.Text := 'CALL listMonth(:pDate, :pAll, :pSort)';
    qList.ParamByName('pDate').AsDate  := aDate;
    qList.ParamByName('pAll').AsInteger   := All;
    qList.ParamByName('pSort').AsString   := '';
    qList.Open;

А это хранимая процедура listMonth в MySQL, в соответствующей базе:
Код: Выделить всё
CREATE DEFINER = 'root'@'localhost'
PROCEDURE cto.listMonth(IN pDate DATETIME, IN pAll TINYINT, IN pSort VARCHAR(255))
BEGIN
  SET @pMonth = MONTH(pDate);
  SET @pYear = YEAR(pDate);
  SET @pr = fPrice(pDate);
  SET @frm = fFirm(@pYear, @pMonth);
  SET @art = fArticle(@pYear, @pMonth);
  SET @fCTO = 6, @fVirta = 3, @fNano = 8, @fPRO = 10, @fCIM = 5;
  SET @s1 = CONCAT('SELECT l.*, ',
    'r.ID ID_CTO, r.Sponsor Sp_CTO, r.Date_Entry Date_CTO, r.Lvl Lvl_CTO, r.DC DC_CTO, r.Deleted Del_CTO, r.Status_CTO, r.Status_Virta, r.Color Color_CTO, r.`Group` Group_CTO, ',
    'pr1.CntPromo1, b1.CTO1, b1.Virta1, b1.SZV1, ',
    'pr2.CntPromo2, b2.CTO2, b2.Virta2, b2.SZV2  ',
    'FROM list l ',
    'LEFT JOIN rcto r ON l.Un = r.Un ',
    'LEFT JOIN (SELECT b.Un, SUM(b.CountBuy) CntPromo1 ',
                'FROM buys b ',
                'WHERE b.Promo = 1 AND YEAR(b.DateOp)=', @pYear, ' AND MONTH(b.DateOp)=', @pMonth, ' ',
                'GROUP BY b.Un) pr1 ON l.Un = pr1.Un ',
    'LEFT JOIN (SELECT b.UN, ',
              'SUM(IF(b.Firm=6,  b.CountBuy*p.Ball_CTO, 0)) CTO1, ',
              'SUM(IF(b.Firm=3,  b.CountBuy*p.Ball_Virta, 0)) Virta1, ',
              'SUM(IF(b.Firm=14, b.CountBuy*p.Ball_SZV, 0)) SZV1 ',
              'FROM buys b ',
              'LEFT JOIN ', @pr,' p ON b.UNP = p.UNP ',
              'WHERE YEAR(b.DateOp)=', @pYear, ' AND MONTH(b.DateOp)=', @pMonth, ' AND b.Promo = 0  AND (Retail in (0, 1)) ',
              'GROUP BY b.Un ',
              'ORDER BY b.Un) b1 ON l.Un = b1.Un ',
    'LEFT JOIN (SELECT r.Un, SUM(r.CountBuy) CntPromo2 ',
              'FROM report r ',
              'WHERE r.Promo = 1 AND YEAR(r.DateOp)=', @pYear, ' AND MONTH(r.DateOp)=', @pMonth,' ',
              'GROUP BY r.Un) pr2 ON l.Un = pr2.Un ',
    'LEFT JOIN (SELECT b.UN, ',
              'SUM(IF(b.Firm=6, b.CountBuy*p.Ball_CTO, 0)) CTO2, ',
              'SUM(IF(b.Firm=3, b.CountBuy*p.Ball_Virta, 0)) Virta2, ',
              'SUM(IF(b.Firm=14, b.CountBuy*p.Ball_SZV, 0)) SZV2 ',
              'FROM report b ',
              'LEFT JOIN ', @pr, ' p ON b.UNP = p.UNP ',
              'WHERE YEAR(b.DateOp)=', @pYear, ' AND MONTH(b.DateOp)=', @pMonth, ' AND b.Promo = 0 AND (Retail in (0, 1)) ',
              'GROUP BY b.Un ',
              'ORDER BY b.Un) b2 ON l.Un = b2.Un ');
  IF pAll=0 THEN
    SET @s2='';
  ELSE 
    SET @s2='WHERE r.Deleted = 0 OR (r.Deleted =1 AND ((b1.CTO1>0) OR (b2.CTO2>0) OR (b1.Virta1>0) OR (b2.Virta2>0) OR (b1.SZV1 > 0) OR (b2.SZV2 > 0))) ';
  END IF;
  IF pSort > '' THEN
    SET @s3 = CONCAT('ORDER BY ', pSort);
  ELSE
    SET @s3='ORDER BY r.Lvl, r.Sponsor ';
  END IF;
  SET @it = CONCAT(@s1, @s2, @s3);
  PREPARE aa FROM @it;
  EXECUTE aa;
END


Добавлено спустя 3 минуты 1 секунду:
А ещё можете воспользоваться, так называемыми представлениями.

"Представления (VIEW) в MySQL

Что такое представление?

Представление (VIEW) — объект базы данных, являющийся результатом выполнения запроса к базе данных, определенного с помощью оператора SELECT, в момент обращения к представлению.

Представления иногда называют «виртуальными таблицами». Такое название связано с тем, что представление доступно для пользователя как таблица, но само оно не содержит данных, а извлекает их из таблиц в момент обращения к нему. Если данные изменены в базовой таблице, то пользователь получит актуальные данные при обращении к представлению, использующему данную таблицу; кэширования результатов выборки из таблицы при работе представлений не производится. При этом, механизм кэширования запросов (query cache) работает на уровне запросов пользователя безотносительно к тому, обращается ли пользователь к таблицам или представлениям.

Представления могут основываться как на таблицах, так и на других представлениях, т.е. могут быть вложенными (до 32 уровней вложенности)
".
sign
энтузиаст
 
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 236

Рейтинг@Mail.ru