为什么我不能用我的光标做到这一点

时间:2018-06-02 23:28:41

标签: oracle plsql

SET SERVEROUTPUT ON;

DECLARE 
  CURSOR test_cursor IS
    SELECT SUM(value), MAX(value), MIN(value), AVG(value), COUNT(*)
    FROM table_name;

  hold_total     table_name.SUM(value)%TYPE;
  hold_max       table_name.MAX(value)%TYPE;    
  hold_min       table_name.MIN(value)%TYPE;    
  hold_avg       table_name.AVG(value)%TYPE;    
  hold_amount    table_name.COUNT(*)%TYPE;

BEGIN

  OPEN test_cursor;

  LOOP 
    FETCH report_cursor INTO hold_total, hold_max, hold_min, hold_avg, hold_amount;
    EXIT WHEN report_cursor%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE('Total          Max           Min           Avg            Amount');

    DBMS_OUTPUT.PUT_LINE('_____          ___           ___           ___            ______');

    DBMS_OUTPUT.PUT_LINE(hold_total || ' ' || hold_max || ' ' || hold_min || '  ' || hold_avg || '  ' || hold_amount);  
  END LOOP;

  CLOSE test_cursor;

END;
/

2 个答案:

答案 0 :(得分:1)

%type语法用于定义其数据类型与表列声明匹配的PL / SQL变量。我们不能这样做......

 table_name.SUM(value)%TYPE; 

...因为SUM(value)不是列。

解决方案非常简单:您的光标正在选择数字聚合,因此您应该将目标变量定义为数字:

hold_total     number;
hold_max       number;
hold_min       number;
hold_avg       number;
hold_amount    number;

或者,您可以为光标投影中的列添加别名,并改为使用%rowtype构造:

DECLARE 
   CURSOR test_cursor IS
      SELECT SUM(value) as hold_total, 
             MAX(value) as hold_max, 
             MIN(value) as hold_min  , 
             AVG(value) as hold_avg , 
             COUNT(*) as hold_amount
      FROM table_name;

    test_rec  test_cursor%ROWTYPE;
BEGIN
  OPEN test_cursor;
  LOOP 
      FETCH report_cursor INTO test_rec;
      EXIT WHEN report_cursor%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE('Total          Max           Min           Avg            Amount');

      DBMS_OUTPUT.PUT_LINE('_____          ___           ___           ___            ______');

      DBMS_OUTPUT.PUT_LINE(test_rec.hold_total || ' ' || test_rec.hold_max || ' ' || 
          test_rec.hold_min || '  ' || test_rec.hold_avg || '  ' || 
          test_rec.hold_amount);

  END LOOP;
  CLOSE test_cursor;
END;

答案 1 :(得分:0)

我从未理解新PL / SQL开发人员中显式游标和费力列出的变量的持久受欢迎程度。这不是更简单吗?

begin
    dbms_output.put_line('        Total          Max          Min          Avg       Amount');
    dbms_output.put_line('-------------  -----------  -----------  -----------  -----------');

    for r in (
        select sum(value) as hold_total
             , max(value) as hold_max
             , min(value) as hold_min
             , avg(value) as hold_avg
             , count(*) as hold_amount
        from   table_name
    )
    loop
        dbms_output.put_line
        ( lpad(r.hold_total,13) || lpad(r.hold_max,13) || lpad(r.hold_min,13) || lpad(r.hold_avg,13) || lpad(r.hold_amount,13) );
    end loop;
end;