16.04.2015 14:12
Starter
 
Не подскажете, как в скрипте sqlplus организовать цикл и вывести результат в файл ?
т.е. получить на выходе файл 1.txt вида:
1
2
3
16.04.2015 14:25
OlegON
 
Про вывод результатов без заголовка я уже миллион раз писал, а так, в зависимости от целей можно сделать через while или, по простому, через
SQL код:
select rownum from all_objects where rownum<4
пиши подробнее, что ты хочешь сделать и в связи с чем.
16.04.2015 14:47
Starter
 
Хочется вывести, предположим, долю продаж по группам товаров.
Пишем код ниже, все работает.
А теперь хочется чтобы данный код выполнился за последний год помесячно и в файл сохранил. Как это циклом организовать ?

Код:
SET echo off newpage 0 space 0 pagesize 0 feedback off head off trimspool on linesize 2000  recsep off verify off

var res_all number;

begin
SELECT round((SUM((nvl(D.SaleSum,0)-nvl(D.RetSum,0)))),4) into :res_all FROM SMStoreLocations LOC,SVARealCostPriceOpenedPeriod D
 WHERE D.StoreLoc=LOC.ID and D.SaleDate between to_date('01.03.2015','DD.MM.YYYY') and to_date('31.03.2015','DD.MM.YYYY');
end;
/
SPOOL rep.csv APPEND
SELECT (CRDCLASS.Name1),round((SUM(nvl(D.RealSum,0)))/:res_all*100,2)
 FROM SVCardClassWithOlderGroup CRDCLASS,SVCardName CRD,(SELECT StoreLoc, Article, sum(RealSum) RealSum FROM (SELECT StoreLoc, Article,to_date('01012000','DDMMYYYY') RepDate,0 MeasNu, 0 RealSum FROM supermag.SVLocCard LC UNION ALL SELECT StoreLoc, Article,CreateDat RepDate,0 MeasNu, RealSum FROM supermag.SVAReal R WHERE R.CreateDat between to_date('01.03.2015','DD.MM.YYYY') and to_date('31.03.2015','DD.MM.YYYY')) GROUP BY StoreLoc, Article) D
 WHERE D.Article=CRD.Article and CRD.IDClass=CRDCLASS.ID
 GROUP BY (CRDCLASS.Name1)
 HAVING (SUM(nvl(D.RealSum,0)))!=0;
SPOOL OFF
exit
16.04.2015 15:19
OlegON
 
Извини, в код погружаться сейчас некогда, если хочешь конкретики, ткни конкретно, куда именно ты 1...12 хочешь воткнуть, НО:

1. Часто правильно генерировать параметры в ОС и передавать их в запрос. Тут же можно и помесячно файлы генерировать. Мне кажется, что это то, что тебе нужно. В недоос есть for в командной строке.
2. При получении суммарных чисел на не очень больших объемах, можно использовать не between, а group by по усеченной дате, т.е. формата 'MM.YYYY', варианты с максимумами и т.п. - partition by. Значительно упрощает код.
3. Можно написать функцию с курсором или while.
4. Можно передать with с таблицей, перечисленных от руки месяцев, их всего-то 12.
16.04.2015 20:48
Starter
 
Код просто для примера.
можно для примера другой -
SQL код:
SET echo off newpage 0 space 0 pagesize 0 feedback off head off trimspool on linesize 2000  recsep off verify off

var res_all number;

begin
SELECT to_number
(To_Char(sysdate'yyyymmdd')) into :res_all from dual;
end;
/
SPOOL rep.csv APPEND
SELECT 
:res_all-1 from dual;
SELECT :res_all-2 from dual;
SELECT :res_all-3 from dual;
SELECT :res_all-4 from dual;
SELECT :res_all-5 from dual;
SPOOL OFF
exit 
Вот в этом коде как организовать цикл, чтобы пять раз не делать select ?


1. Тоже вариант, если не получится в SQL, так и придется делать. Проблема в том, что в недоос с for тоже нужно будет разобраться. Как там организовать цикл с перебором интервалов дат - экспериментировать нужно.
2. Код был только для примера, но на будущее учтем.
3. функцию написать прямо в скрипте ? или в базе эту функцию держать ?
4. непонял.
17.04.2015 09:48
OlegON
 
1. Ты уж определись, какой цикл тебе нужен, а то 1..5, месяцы, интервалы дат... Кстати, в PL\SQL тоже циклы for есть.
3. Встроенную функцию, в БД.
4. Есть оператор with ... as, тут примеры были.
по примеру пример
SQL код:
select trunc(sysdate)-(6-numfrom (select rownum num from dual connect by rownum <= 5); 
17.04.2015 11:46
kadr
 
А обязательно чистый SQL? PL/SQL не прокатит?
Часовой пояс GMT +3, время: 18:58.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.