Пакетные запросы
Модератор: Модераторы
Пакетные запросы
Здравствуйте. Вы не подскажите как в Lazarus с помощью TSQLQuery или другим компонентом можно сделать пакетный запрос. Например мне сначала надо сделать выборку по одной таблице, а уже результаты выборки будут использоваться в другом запросе?
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
Это не к Lazarus и его компонентам вопрос должен быть, а к серверу базы данных. Как вы средствами конкретной базы свои потребности реализуете. А компоненты только передают запросы серверу и получают от него результаты.
Ну например мне нужно сделать зарос
Select * From Table1
и потом уже результат этого запроса, например пусть он будет Table1Tmp
выполнить в другом запросе
Select * from Table2 Left Join Table1Tmp.Id = Table2.id
Как это можно реализовать в Лазарусе?
Select * From Table1
и потом уже результат этого запроса, например пусть он будет Table1Tmp
выполнить в другом запросе
Select * from Table2 Left Join Table1Tmp.Id = Table2.id
Как это можно реализовать в Лазарусе?
-
Padre_Mortius
- энтузиаст
- Сообщения: 1265
- Зарегистрирован: 29.05.2007 17:38:07
- Откуда: Спб
Код: Выделить всё
select * from Table2 t2 left join Table1 t1 on t1.Id=t2.Id Вроде как-то так
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
bogdan писал(а):Как это можно реализовать в Лазарусе?
Повторяю, это реализуется НЕ в лазарусе, а НА СЕРВЕРЕ. Вы не сообщаете, с каким сервером баз данных вы намерены работать. Но большинство распространенных поддерживают создание временных таблиц и встроенных функций. Вот этими средствами ваша задача и решается. Как создавать такие таблицы и функции смотрите в описании языка SQL соответствующего сервера.
bogdan писал(а):Например мне сначала надо сделать выборку по одной таблице, а уже результаты выборки будут использоваться в другом запросе?
Это уже к Паскалю не относится, тут чисто язык SQL сервера
bogdan писал(а):Вы не подскажите как в Lazarus с помощью TSQLQuery или другим компонентом можно сделать пакетный запрос.
Как сделать пакетный и любой иной SQL запрос на сервер можно узнать, прочитав статьи на этом сайте (не на форуме) о базах данных
http://freepascal.ru/article/lazarus/20090416150500/
почитай про синтаксис sql сначало. про представления, обьединения и прочее.
bogdan писал(а):надо сделать выборку по одной таблице, а уже результаты выборки будут использоваться в другом запросе?
Например так.
Код: Выделить всё
select * from table2 t2 where t2.id in (select id from table1) - Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
Если что-то достаточно сложное, то можно использовать временные таблицы. Вот как я делал в одной программе (mysql):
В mysql временная таблица существует в пределах одной сессии и автоматически уничтожается при дисконнекте.
Код: Выделить всё
CREATE TEMPORARY TABLE IF NOT EXISTS tmpuserscall ...
//описание таблицы
... ENGINE=HEAP;
TRUNCATE tmpuserscall;
INSERT INTO tmpuserscall SELECT ...
//заполняем таблицу
SELECT ...
FROM tmpuserscall, ...
В mysql временная таблица существует в пределах одной сессии и автоматически уничтожается при дисконнекте.
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 уровней вложенности)".
