在oracle中开始后声明游标10g

时间:2017-12-25 10:43:57

标签: oracle plsql

我正在编写以下代码块:

select companyid into compid from person where signedin = 1;
cursor getpending is select serviceid from servnego where companyid = compid and confirmed = 0;
open getpending;
loop
    exit when getpending%notfound;
    fetch getpending into servid;
    select servname into s from service where id = servid;
    add_list_element('homeadmin1.listpendingservice', counter2,s,s);
    counter2 := counter2 + 1;
end loop;

这是开始/结束内部代码的一部分。游标的取消取决于它之前的select语句中的变量compid的值。编译时,我在光标行上出现错误:“遇到以下其中一个时遇到符号getpending:...”,因此在开始部分中光标声明时出错。我该如何解决这个问题?任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

游标与任何其他变量一样,需要在声明部分声明。但是,您可以使用参数...

声明它
declare
    ....
    cursor getpending (p_compid number) is 
        select serviceid from servnego 
        where companyid = p_compid 
        and confirmed = 0;
declare
    select companyid into compid 
    from person 
    where signedin = 1;
    open getpending (compid );
    loop
        fetch getpending into servid;
        exit when getpending%notfound;
        select servname into s 
        from service 
        where id = servid;
        add_list_element('homeadmin1.listpendingservice', counter2,s,s);
        counter2 := counter2 + 1;
    end loop;
    close getpending;

请注意,您需要在执行提取后测试光标%notfound 。否则,光标耗尽时会出错。另外,请记住在退出循环后关闭光标。

答案 1 :(得分:1)

您可以合并CURSOR中的第一个查询。还要注意 exit when语句应该在FETCH

之后
 DECLARE
    CURSOR getpending IS
      SELECT serviceid
      FROM   servnego
      WHERE  companyid IN (SELECT companyid 
                            FROM   person
                           WHERE  signedin = 1)
             AND confirmed = 0;
--declare  s and counter2 here appropriately.
BEGIN
    OPEN getpending;

    LOOP
        FETCH getpending INTO servid;

        exit WHEN getpending%NOTFOUND;

        SELECT servname
        INTO   s
        FROM   service
        WHERE  id = servid;

        Add_list_element('homeadmin1.listpendingservice', counter2, s, s);

        counter2 := counter2 + 1;
    END LOOP;
END;

/  

答案 2 :(得分:1)

我建议尽可能使用游标for循环。 Oracle通过批量绑定提取来自动优化游标for循环,从而减少了到数据库的往返次数,从而提高了性能。另外,尽量在单个SQL语句中执行尽可能多的工作:

UPDATE TEST SET t_status = 'X' where t_status = 'T' and t_moddate <= now()- interval(45 minutes);

这也有助于摆脱不必要的临时变量,这些变量导致与存储在多个地方的值相关的问题,这绝不是一件好事。

祝你好运。