Рассчитать сумму 2 переменных из разных курсоров - функция Pl / sql - PullRequest
0 голосов
/ 07 сентября 2011

Я относительно новичок в pl / sql и кодировании в целом и ценю вашу помощь.Есть 2 таблицы следующим образом.Написание функции для вычисления суммы (amt1) + sum (amt2) для диапазона дат.

Я не могу связать table1 и table2 напрямую, так как это дает плохие результаты.У меня есть курсор для расчета суммы (amt1) из таблицы1 и другой курсор для расчета суммы (amt2) из ​​таблицы2.Как рассчитать сумму (amt1) + сумма (amt2) из ​​этих 2 курсоров

Table 1

Id  Amt Date
1   342 21-May-02
2   421 30-Mar-01
3   598 4-May-11
2   843 14-Jun-12
4   457 21-May-09
1   2346    24-Apr-98

Table 2


Id  Amt2    Date2
1   342 21-May-02
2   421 30-Mar-01
3   598 4-May-11
2   843 14-Jun-12
4   457 21-May-09
1   2346    24-Apr-98

Это моя функция, которая была скомпилирована, но когда я проверяю ее, она не возвращает никакого значения

CREATE OR REPLACE FUNCTION FZ_HH_BY_DATE_COMMITMENT (pidm          number,
                                                     start_date    date,
                                                     end_date      date,
                                                     desg          varchar2)
   RETURN number
AS
     total_commit   number(13,2) := 0;
   total_gifts    number(13,2) := 0;
   total_pledges  number(13,2) := 0;
   sp_pidm        number (9);

  CURSOR date_commit_gifts IS
  SELECT SUM(azvglst_amt) FROM acu.azvglst
  WHERE  azvglst_pidm IN (pidm, sp_pidm)
  AND SUBSTR (azvglst_desg, 0, LENGTH (desg)) = desg
  AND azvglst_gift_date BETWEEN start_date AND end_date
  AND azvglst_pledge_no = '0000000'
  AND (azvglst_pgve_code <> '3P' OR azvglst_pgve_code IS NULL);


  CURSOR all_date_commit_gifts IS
  SELECT SUM(azvglst_amt) FROM acu.azvglst
  WHERE  azvglst_pidm IN (pidm, sp_pidm)
  AND azvglst_gift_date BETWEEN start_date AND end_date
  AND azvglst_pledge_no = '0000000'
  AND (azvglst_pgve_code <> '3P' OR azvglst_pgve_code IS NULL);


   CURSOR date_commit_pledges
   IS
      SELECT   SUM (agvplst_amt_pledged)
              FROM   agvplst
       WHERE   agvplst_pledge_date BETWEEN start_date AND end_date
               AND SUBSTR (agvplst_desg, 0, LENGTH (desg)) = desg
               AND agvplst_pidm IN (pidm, sp_pidm)
               AND agvplst_psta_code NOT IN ('I','C','U');

   CURSOR all_date_commit_pledges
   IS
      SELECT   SUM (agvplst_amt_pledged)
              FROM   agvplst
       WHERE   agvplst_pledge_date BETWEEN start_date AND end_date
                              AND agvplst_pidm IN (pidm, sp_pidm)
                              AND agvplst_psta_code NOT IN ('I','C','U');
BEGIN
   sp_pidm := TO_NUMBER (fz_split_fields (fz_spouse_info (pidm), 1));

   IF desg IS NULL
   THEN
      OPEN all_date_commit_gifts;
      FETCH all_date_commit_gifts INTO   total_gifts;
      CLOSE all_date_commit_gifts;

      OPEN all_date_commit_pledges;
      FETCH all_date_commit_pledges INTO total_pledges;
      CLOSE all_date_commit_pledges;

      ELSE OPEN date_commit_gifts;
      FETCH date_commit_gifts INTO   total_gifts;
      CLOSE date_commit_gifts;

      OPEN date_commit_pledges;
      FETCH date_commit_pledges INTO total_pledges;
      CLOSE date_commit_pledges;
      END IF;
      total_commit := total_gifts + total_pledges;
      RETURN total_commit;

END;

Ответы [ 2 ]

1 голос
/ 07 сентября 2011

ОБНОВЛЕНО:

CREATE OR REPLACE FUNCTION CALC_BY_DATE(
    start_date DATE,
    end_date DATE)
    RETURN NUMBER
IS
  sum_amt NUMBER;
BEGIN
  SELECT SUM(AMT)
  INTO   sum_amt
  FROM   (
         SELECT AMT
         FROM   TABLE1
         WHERE  DATE >= start_date
         AND    DATE < end_date + 1
         UNION ALL
         SELECT AMT
         FROM   TABLE2
         WHERE  DATE >= start_date
         AND    DATE < end_date + 1
         );

  RETURN(NVL(sum_amt, 0));
END;

Кстати, это нормально, если вы просто используете select ... into вместо открытого курсора, выборки, закрытия.

Это было давно, когда это имело какое-то значение в отношении производительности запросов.

ОДНА БОЛЬШЕ

Наиболее вероятная проблема - строка:

total_commit := total_gifts + total_pledges

вы должны использовать:

total_commit := NVL(total_gifts, 0) + NVL(total_pledges, 0)

Помните, что если вы что-либо суммируете с NULL, вы ВСЕГДА получаете NULL.

С уважением.

0 голосов
/ 07 сентября 2011

Без двух курсоров вы можете сделать:

select id, sum(amt) from
( select id, amt1 as amt from table1
  union all
  select id, amt2 as amt from table2
)
group by id
...