Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Из строкового списка получить набор строк  [new]
Alibek B.
Member

Откуда:
Сообщений: 3936
Есть список задач. У каждой задачи есть список объектов, для которых рассчитываются некоторые начисления.
По окончанию месяца нужно выбрать все задачи этого месяца, просуммировать начисления, округлить вниз до целых.
Если сумма получилась нулевая, то объект пропускается.
После окончания обработки у объектов и задач меняется статус (в зависимости от того, было проведено начисление или пропущено).

Сделал я примерно таким образом.
+

  PROCEDURE CA_REFUND(p_accident NUMBER, p_date DATE, p_period DATE, res OUT recResultOut) AS
    CURSOR cur_rcpt (filter_accident NUMBER, filter_date DATE, filter_period DATE) IS
      select
        case
          when filter_accident is not null then 'инцидент ' || filter_accident
          when filter_date     is not null then to_char(filter_date,   'DD.MM.YYYY')
          when filter_period   is not null then to_char(filter_period, 'FMmonth YYYY', 'NLS_DATE_LANGUAGE=russian')
        end as "MODE"
        , C.CUSTOMER_ID as CLIENT
        , RS.IDS
        , RS.INC
        , RS.QTY
        , RS.CNT
        , RS.SUM
      from (
        select RS.ACCOUNT_ID
        , wm_concat(RS.ACCIDENT_ID) as IDS
        , count(distinct RS.ACCIDENT_ID) as INC
        , count(distinct RS.SERVICE_ID) as QTY
        , count(*) as CNT
        , trunc(sum(RS.RECALC)) as SUM
        from (
          select ...
          from ...
          where ...
          and (filter_accident is null or (AL.ACCIDENT_ID = filter_accident) )
          and (filter_date     is null or (AL.MOMENT_END >= filter_date   and AL.MOMENT_END < (filter_date+1)) )
          and (filter_period   is null or (AL.MOMENT_END >= filter_period and AL.MOMENT_END < add_months(filter_period, 1)) )
        ) RS
        group by RS.ACCOUNT_ID
      ) RS
      join CUSTOMERS C on (...)
      ;
    rec_rcpt cur_rcpt%ROWTYPE;
  BEGIN
    ...
    open cur_rcpt(p_accident, trunc(p_date), trunc(p_period, 'MM'));
    loop
      fetch cur_rcpt into rec_rcpt;
      exit when cur_rcpt%NOTFOUND;
      v_num := v_num + 1;
      if (rec_rcpt.SUM = 0) then
        v_skip := v_skip + 1;
        merge into ACCIDENT_RCPT T
        using (
          select AR.ACCIDENT_ID, AR.CLIENT
          from ACCIDENT_RCPT AR
          join (select distinct regexp_substr(rec_rcpt.IDS, '[^,]+', 1, level) ACCIDENT_ID from dual connect by level <= rec_rcpt.CNT) IDS on (IDS.ACCIDENT_ID = AR.ACCIDENT_ID)
          where AR.CUSTOMER_ID = rec_rcpt.CLIENT
        ) RS on (RS.ACCIDENT_ID = T.ACCIDENT_ID and RS.CLIENT = T.CLIENT)
        when matched then update set MOMENT = sysdate, STATUS = -1
        ;
      else
        v_cnt := v_cnt + 1;
        v_sum := v_sum + rec_rcpt.SUM;
        merge into ACCIDENT_RCPT T
        using (
          select AR.ACCIDENT_ID, AR.CLIENT
          from ACCIDENT_RCPT AR
          join (select distinct regexp_substr(rec_rcpt.IDS, '[^,]+', 1, level) ACCIDENT_ID from dual connect by level <= rec_rcpt.CNT) IDS on (IDS.ACCIDENT_ID = AR.ACCIDENT_ID)
          where AR.CUSTOMER_ID = rec_rcpt.CLIENT
        ) RS on (RS.ACCIDENT_ID = T.ACCIDENT_ID and RS.CLIENT = T.CLIENT)
        when matched then update set MOMENT = sysdate, STATUS = 4
        ;
      end if;
    end loop;
    close cur_rcpt;
    ...
  END;



Поскольку в списке у меня только числа, разделены они запятой и количество чисел мне известно, то удалось разбить текст на строки с помощью connecy by (regexp_substr).
А можно ли использовать сразу OdciNumberList, чтобы передавать ему не список значений, а одну строку?
5 июн 21, 14:23    [22331744]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить