powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Зависает цикл Loop
9 сообщений из 9, страница 1 из 1
Зависает цикл Loop
    #39992237
takini23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Есть задача отправлять каждый день отчет (около 85к строк) в формате CSV

Проблема в том что при выполнении цикл на таком объеме зависает
Кусок кода
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
DECLARE 

v_attach_clob  CLOB := 'PERSONAL_ACCOUNT_NUMBER'||';'||'MSISDN'||';'||'SERVICE_NAME'||';'||'DATE_FROM'||';'||'DATE_TO';

  BEGIN

        for x in (--- ВЫГРУЗКА ПО Разовым услугам --

select 
pa.personal_account_number|| ';' ||td.msisdn|| ';' ||s.service_name|| ';' ||to_char(tds.date_from,'dd.mm.yyyy hh24:mi:ss')|| ';' ||to_char(tds.date_to,'dd.mm.yyyy hh24:mi:ss') as STR
from cust.personal_account pa, cust.personal_account_td ptd, cust.terminal_device td , cust.terminal_device_service tds, service s
where 1=1
and pa.personal_account_id=ptd.personal_account_id
and ptd.terminal_device_id=td.terminal_device_id
and td.tariff_plan_id in (61,81,161,162,163,164,165,166)
and td.msisdn not like '7741%')

    LOOP
        v_attach_clob := v_attach_clob || chr(25) || x.str;
    END LOOP;
  
    /***********/

END;



Предположу что здесь проще построить my_View на основе запроса и использовать BULK COLLECT.



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Declare

 v_attach_clob  CLOB := 'PERSONAL_ACCOUNT_NUMBER'||';'||'MSISDN'||';'||'SERVICE_NAME'||';'||'DATE_FROM'||';'||'DATE_TO';
  TYPE t_bulk_collect_test_tab IS TABLE OF my_view%ROWTYPE;

  l_tab t_bulk_collect_test_tab;

  CURSOR c_data IS
    SELECT * FROM my_view;

BEGIN
  OPEN c_data;
  LOOP
    FETCH c_data BULK COLLECT INTO l_tab ;
    EXIT WHEN l_tab.count = 0;

  End loop;
    
  CLOSE c_data;
End;
    




Но тогда где прописывать условие ?
Код: plsql
1.
2.
3.
LOOP
        v_attach_clob := v_attach_clob || chr(25) || x.str;
    END LOOP;
...
Рейтинг: 0 / 0
Зависает цикл Loop
    #39992252
ASNexus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
takini23,

Если это реальный фрагмент кода (без вырезания чего-либо перед публикацией на форуме), то первое, что может стать причиной "зависания":
Код: plsql
1.
2.
3.
4.
5.
6.
from cust.personal_account pa, cust.personal_account_td ptd, cust.terminal_device td , cust.terminal_device_service tds, service s
where 1=1
and pa.personal_account_id=ptd.personal_account_id
and ptd.terminal_device_id=td.terminal_device_id
and td.tariff_plan_id in (61,81,161,162,163,164,165,166)
and td.msisdn not like '7741%')


где условия соединения для таблиц cust.terminal_device_service tds и service s ?

Если просто выполнить этот запрос, что и за какое время он возвращает?

По второму варианту с коллекцией: если Вы не используете LIMIT в FETCH ... BULK COLLECT, то зачем вокруг него цикл?

А вот, чтобы выгруженные строки засунуть в CLOB нужно пройти в цикле по коллекции:
Код: plsql
1.
2.
3.
4.
FOR i IN l_tab.FIRST .. l_tab.LAST
LOOP
     v_attach_clob := v_attach_clob || chr(25) || l_tab(i). ...;
END LOOP;
...
Рейтинг: 0 / 0
Зависает цикл Loop
    #39992264
takini23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ASNexus,спасибо за ответ.
Да,соединение есть

Проблем в том что при выполнении
Код: plsql
1.
2.
3.
LOOP
     v_attach_clob := v_attach_clob || chr(25) || l_tab(i). ...;
END LOOP;



Нарываюсь на ошибку

PLS-00306: wrong number or types of arguments in call to '||'


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
Declare

 v_attach_clob  CLOB := 'PERSONAL_ACCOUNT_NUMBER'||';'||'MSISDN'||';'||'SERVICE_NAME'||';'||'DATE_FROM'||';'||'DATE_TO';
  TYPE t_bulk_collect_test_tab IS TABLE OF my_view%ROWTYPE;

  l_tab t_bulk_collect_test_tab;

  CURSOR c_data IS
    SELECT * FROM my_view;

BEGIN
  OPEN c_data;
  LOOP
    FETCH c_data BULK COLLECT INTO l_tab ;
    FOR i IN l_tab.FIRST .. l_tab.LAST
LOOP
     v_attach_clob := v_attach_clob || chr(25) || l_tab(i);
END LOOP;
    EXIT WHEN l_tab.count = 0;

  End loop;
    
  CLOSE c_data;
End;
    
...
Рейтинг: 0 / 0
Зависает цикл Loop
    #39992270
Asmodeus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
takini23, не ваш случай ?
...
Рейтинг: 0 / 0
Зависает цикл Loop
    #39992273
ASNexus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
takini23,

Ну нельзя же так, из двух циклов перемешали все в кучу. И "..." я написал для того, чтобы показать, что нельзя в этом месте l_tab(i) использовать "как есть", а нужно расписывать - конкатенация соединяет строки (и то, что к ним может быть неявно приведено), вы же в первоначальном запросе x.str как получали, вот так-же и здесь нужно поля перечислять.

В общем примерно так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CURSOR c_data IS SELECT * FROM my_view;
BEGIN
  OPEN c_data;
  FETCH c_data BULK COLLECT INTO l_tab ;
  CLOSE c_data;
  FOR i IN l_tab.FIRST .. l_tab.LAST
  LOOP
     v_attach_clob := v_attach_clob || chr(25) || l_tab(i).personal_account_number || ';' ||  l_tab(i).msisdn|| ';' || l_tab(i).service_name || ... и т.д. и т.п.
  END LOOP;
End;


P.S. Создание VIEW для решения только этой задачи смысла не имеет - можно в определении курсора с таким-же успехом использовать и первоначальный запрос.
...
Рейтинг: 0 / 0
Зависает цикл Loop
    #39992490
takini23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ASNexus,спасибо за помощь. Добавил недостающие данные и наткнулся на ошибку

ORA-06502: PL/SQL: numeric or value error

Ошибка уходит если внутри цикла прописать условие
Код: plsql
1.
2.
EXIT WHEN c_data%NOTFOUND или 
EXIT WHEN l_tab.count < 85784 --точное кол-во строк в выборке



Но в этом случае приходит только одна строка

Пробовал поставить условие IF l_tab.count>0 перед FOR i ,не помогло. Возможно знайте что добавить ?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
Declare

  v_attach_clob CLOB := 'PERSONAL_ACCOUNT_NUMBER' || ';' || 'MSISDN' || ';' ||
                        'SERVICE_NAME' || ';' || 'DATE_FROM' || ';' ||
                          'DATE_TO'
   ;
  TYPE t_bulk_collect_test_tab IS TABLE OF my_view%ROWTYPE;

  l_tab t_bulk_collect_test_tab;

  CURSOR c_data IS
    select * from my_view;
BEGIN
  OPEN c_data; 
  FETCH c_data BULK COLLECT
    INTO l_tab ;
    DBMS_OUTPUT.put_line(l_tab.count);
    
    FOR i IN l_tab.FIRST .. l_tab.LAST LOOP
      v_attach_clob := v_attach_clob || chr(13) || l_tab(i)
                      .PERSONAL_ACCOUNT_NUMBER || ';' || l_tab(i).msisdn || ';' || l_tab(i)
                 .service_name || ';' || l_tab(i).date_from || ';' || l_tab(i).DATE_TO;
  --EXIT WHEN l_tab.count = 85784; 
  -- EXIT WHEN c_data%NOTFOUND ;       
    END LOOP;

  CLOSE c_data;
End;
...
Рейтинг: 0 / 0
Зависает цикл Loop
    #39992508
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
takini23
ASNexus,спасибо за помощь. Добавил недостающие данные и наткнулся на ошибку

ORA-06502: PL/SQL: numeric or value error


... character string buffer too small

22186921

.....
stax
...
Рейтинг: 0 / 0
Зависает цикл Loop
    #39993551
Lion_Kh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а может для начала сборку лоба сделать правильно? через dbms_lob.append ?
...
Рейтинг: 0 / 0
Зависает цикл Loop
    #39993747
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lion_Kh,

для начала можна просто посчитать длину
v_l := v_l+lengthb( x.str)+1;
.....
stax
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Зависает цикл Loop
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]