查询Oracle PLSQL

时间:2011-10-12 05:38:05

标签: oracle plsql cursor

这是我运行以下脚本时收到的错误消息

    ERROR at line 1:
    ORA-00979: not a GROUP BY expression
    ORA-06321: at "s3398293.P2", line 7
    ORA-06321: at "s3398293.P2", line 18
    ORA-06321: at line 1


    create or replace 
    PROCEDURE p2(x NUMBER ) 
    as
        staff_info  staff.bno%TYPE;
        address_info varchar2(20);

            CURSOR c1 IS
                SELECT staff.bno ,
                branch.street || ' ' || branch.suburb || ' ' || branch.postcode 
                FROM deal , staff, contact , property , branch
                where staff.peid = contact.peid
                and contact.pno = property.pno
                and property.pno = deal.pno 
                and staff.peid = branch.peid
                group by staff.bno
                HAVING x > sum(deal.price);

    BEGIN
         OPEN c1;
         LOOP
            FETCH c1 INTO staff_info,address_info ;
            EXIT WHEN c1%notfound;
            dbms_output.put_line('BRANCH# '||' '||'ADDRESS');
            dbms_output.put_line(staff_info ||' '|| address_info);  
         END LOOP;
         close c1;
    END;
    /

我正在尝试获取Staff.bno和分支的地址,其中x>总和(deal.price)

    Can Someone tell me more about GROUP BY EXPRESSION! ?

2 个答案:

答案 0 :(得分:2)

您需要在分组后将x > sum(deal.price)移动到HAVING子句中。您编写的内容无效(忽略double WHERE)因为在SUM / GROUP BY之前计算了where子句。 e.g。

SELECT staff.bno ,
        branch.street||' '||branch.suburb||' '||branch.postcode 
FROM deal , staff, contact , property 
where staff.peid = contact.peid
and contact.pno = property.pno
and property.pno = deal.pno 
group by staff.bno, branch.street||' '||branch.suburb||' '||branch.postcode
HAVING x > sum(deal.price);

编辑:忘记按您选择的其他表达式进行分组。

答案 1 :(得分:1)

您的代码的一个明显问题是CURSOR。游标是变量,因此需要在DECLARATION部分中定义。然后你需要打开包体中的curosr。您还需要检查FETCH是否实际检索了一行。

create or replace 
    PROCEDURE p2(x NUMBER ) 
    as
       CURSOR c1 for
            SELECT staff.bno ,
                branch.street||' '||branch.suburb||' '||branch.postcode
                FROM deal , staff, contact , property 
                where staff.peid = contact.peid
                and contact.pno = property.pno
                and property.pno = deal.pno 
                group by staff.bno
                HAVING x > sum(deal.price);
      staff_info  staff.bno%TYPE;
      address_info address%TYPE;
    BEGIN
         open c1;
         loop
            fetch c1 into staff_info,address_info ;
            exit when c1%notfound;
            dbms_output.put_line('BRANCH# '||' '||'ADDRESS');
            dbms_output.put_line(staff_info ||' '|| address_info);  
         end loop;
         close c1;
    END;

通常不需要这样的游标。使用隐式游标更有效。

create or replace 
    PROCEDURE p2(x NUMBER ) 
    as
    BEGIN
         for r in ( SELECT staff.bno ,
                           branch.street||' '||branch.suburb||' '||branch.postcode as address_info
                    FROM deal , staff, contact , property 
                    where staff.peid = contact.peid
                    and contact.pno = property.pno
                    and property.pno = deal.pno 
                    group by staff.bno
                    HAVING x > sum(deal.price))
         loop
            dbms_output.put_line('BRANCH# '||' '||'ADDRESS');
            dbms_output.put_line(r.bno ||' '|| r.address_info);  
         end loop;
    END;