"无效的光标"运行重载的PLSQL存储过程时出错

时间:2015-06-22 23:04:09

标签: oracle stored-procedures plsql

我正在创建一个重载的PLSQL存储过程,它允许显示学校的名称,它们对应的类别(小学等)以及它们所属的邻域。

学校名称取自字段OTTAWASCHOOLS中的表NAME。该类别来自字段OTTAWASCHOOLS中的表格CATEGORY

此外,用户可以选择输入特定的社区,以查找该社区中学校的上述信息。邻域的名称取自字段OTTAWANEIGHBOUR中的NAME表。

但是,如果用户没有输入特定的邻域,则输出将显示OTTAWASCHOOLS表中所有学校的名称及其各自的邻域和类别

(目前我只创建了一个程序)。

我的代码如下

SET SERVEROUTPUT ON;
SET VERIFY OFF

CREATE OR REPLACE PACKAGE schools_package 
AS

PROCEDURE find_school
(neighbourhood_name     IN  OTTAWANEIGHBOUR.NAME%TYPE);
END schools_package;
/

CREATE OR REPLACE PACKAGE BODY schools_package
AS
PROCEDURE find_school
(neighbourhood_name     IN  OTTAWANEIGHBOUR.NAME%TYPE)
IS

school_category             OTTAWASCHOOLS.CATEGORY%TYPE;
school_name                 OTTAWASCHOOLS.NAME%TYPE;
v_neighbourhood_name        OTTAWANEIGHBOUR.NAME%TYPE;

CURSOR c_schools IS
SELECT NAME, CATEGORY
FROM eluliGDM.OTTAWASCHOOLS;

r_schools c_schools%ROWTYPE;

BEGIN
FOR r_schools IN c_schools
    LOOP
    SELECT c1.NAME, c2.NAME, c2.CATEGORY
    INTO v_neighbourhood_name, school_name, school_category
    FROM eluliGDM.OTTAWANEIGHBOUR c1, eluliGDM.OTTAWASCHOOLS c2
    WHERE  SDO_RELATE (c2.GEOMETRY, c1.GEOMETRY, 'MASK=INSIDE+COVEREDBY QUERYTYPE=JOIN') = 'TRUE'
    AND c2.NAME=r_schools.NAME;


    DBMS_OUTPUT.PUT_LINE ('NEIGHBOURHOOD  ' || 'CATEGORY  '|| 'SCHOOL NAME  ');
    DBMS_OUTPUT.PUT_LINE ('-------------  ' || '--------  '|| '-----------  ');
    DBMS_OUTPUT.PUT_LINE (v_neighbourhood_name || school_category|| school_name);
END LOOP;
CLOSE c_schools;
END find_school;
END schools_package;

-----------TESTING STORED PROCEDURE---------------
Execute schools_package.find_school();
Execute schools_package.find_school('Mer Bleue');

但是当我测试程序时,我收到一个错误:01001. 00000 - "invalid cursor"然后继续向我展示所有社区及其相应的学校。我的光标出了什么问题?

2 个答案:

答案 0 :(得分:0)

删除CLOSE c_schools;声明。 Cursor For Loop已经完成了这个工作。见Oracle Docs

“游标FOR LOOP语句隐式声明其循环索引为指定游标返回的行类型的记录变量,然后打开游标。每次迭代时,游标FOR LOOP语句从结果集中获取一行当没有更多行要获取时,游标FOR LOOP语句将关闭光标。“

答案 1 :(得分:0)

根据您的输入,OTTAWASCHOOLS包含NAME和CATEGORY列,因此光标本身似乎是有效定义的。

OTOH,架构eluliGDM是否拥有表和包?如果那不是包主人,也许有特权问题?如果架构相同,为什么要在代码中指定架构?如果不相同,请考虑使用同义词并从代码中删除硬编码模式。

我不确定你为什么有输入参数;你没有使用它。所以,我并不感到惊讶你得到了所有的学校;游标没有谓词所以它是完整的表,并且LOOP内的SELECT连接两个表中NAME列相同的地方。没有任何基于输入参数的限制,除连接之外根本没有过滤器。

HTH