1

有人可以帮我解决以下问题。编写光标很容易,但我不知道如何测试何时REFVAL更改。到目前为止,我的光标如下。

光标不能在 上分组REFVAL。可以将其视为基于需要为该发票上的总框添加的一系列发票行。

就像是:

REFVAL           PAYAMNT       INVOICE_DETAIL

12/00001/DA      £420          Recurring fee
12/00001/DA      £300          CRB check
12/00001/DA      £170          Plate fee
12/00002/JV      £70           SQL assistance
12/00002/JV      £30           Loader assistance

因此,当单步浏览光标时,我可以将详细信息从12/00001/DA三行写入,然后写总计12/00001/DA (£890),然后从详细信息12/00002/JV,然后是该行的摘要行。

因此,脚本需要知道何时REFVAL更改

到目前为止我所拥有的是:

DECLARE
  CURSOR c1 IS 
     SELECT refval,amt from johan;

  Grandtotal INTEGER := 0;
  REF_total  Integer := 0;
  REFVAL     varchar(20);
BEGIN
  OPEN c1;
  LOOP
    FETCH c1 INTO refval,ref_total;
    IF c1%notfound THEN
      EXIT;
    END IF;

     dbms_output.put_line('TOtal for '|| refval || ': ' || ref_total);
     Grandtotal := Grandtotal + ref_total;
   END LOOP;

   IF c1%ISOPEN THEN  -- cursor is open
     CLOSE c1;
   END IF;

   dbms_output.put_line('Grandtotal: '||Grandtotal);
 END;
 /
4

2 回答 2

3

如果我正确理解了您的要求,则不需要对数据进行程序处理,可以在 SQL 中使用子句rollup扩展group by来计算总计和总计。这是一个例子:

SQL> with t1 as(
  2    select '12/00001/DA' as REFVAL,  420 as PAYAMNT, 'Recurring fee' as INVOICE_DETAIL from dual union all
  3    select '12/00001/DA',  300,   'CRB check' from dual union all
  4    select '12/00001/DA',  170,   'Plate fee' from dual union all
  5    select '12/00002/JV',  70 ,   'SQL assistance' from dual union all
  6    select '12/00002/JV',  30 ,   'Loader assistance' from dual
  7  )
  8  select nvl(REFVAL, 'GRAND TOTAL:') as REFVAL
  9       , case
 10             when (INVOICE_DETAIL is null) and (REFVAL is not null)
 11             then 'SUB-TOTAL:'
 12             else INVOICE_DETAIL
 13         end  as INVOICE_DETAIL
 14       , sum(PAYAMNT)
 15        
 16     from t1
 17    group by rollup(REFVAL, INVOICE_DETAIL)
 18  ;

REFVAL       INVOICE_DETAIL           END
------------ ----------------- ----------
12/00001/DA  CRB check                300
12/00001/DA  Plate fee                170
12/00001/DA  Recurring fee            420
12/00001/DA  SUB-TOTAL:               890

12/00002/JV  SQL assistance            70
12/00002/JV  Loader assistance         30
12/00002/JV  SUB-TOTAL:               100

GRAND TOTAL:                          990

8 rows selected 
于 2012-12-07T14:48:18.243 回答
1
DECLARE
   CURSOR c1
   IS
      SELECT   refval,
               amt,
               DENSE_RANK () OVER (PARTITION BY REFVAL ORDER BY rowid) rnk   
        FROM   johan;

   Grandtotal   INTEGER := 0;
   REF_total    INTEGER := 0;
   REFVAL       VARCHAR (20);
   v_new_rank   PLS_INTEGER;  
   v_old_rank   PLS_INTEGER;
   v_start      PLS_INTEGER := 1;    --just to intialize v_old_rank
BEGIN
   OPEN c1;

   LOOP
      FETCH c1 INTO   refval, ref_total, v_new_rank;

      EXIT WHEN c1%NOTFOUND;

      IF v_start = 1
      THEN
         v_old_rank := v_new_rank;
         v_start := v_start + 1;
      END IF;

      DBMS_OUTPUT.put_line ('TOtal for ' || refval || ': ' || ref_total);
      Grandtotal := Grandtotal + ref_total;

      IF v_old_rank <> v_new_rank
      THEN
         v_old_ref_val := v_new_rank;

   --you can print the total per refval group
    DBMS_OUTPUT.PUT_LINE ('do something');
      END IF;
   END LOOP;

   IF c1%ISOPEN
   THEN
      -- cursor is open
      CLOSE c1;
   END IF;

   DBMS_OUTPUT.put_line ('Grandtotal: ' || Grandtotal);
END;
/

当您从光标 c1 中选择时,如下图所示

REFVAL           PAYAMNT              rnk

12/00001/DA      £420                 1
12/00001/DA      £300                 1
12/00001/DA      £170                 1
12/00002/JV      £70                  2
12/00002/JV      £30                  2
于 2012-12-07T14:28:40.537 回答