PL/SQL 游标中的简单常见错误 ORA-06550

问题描述

这是一个简单的 PL/sql 块,我有一个非常简单的错误,ORA-06550 但我找不到它,请帮我解决这个错误.........

问题:显示最昂贵物品的类别明智奖

create table menu
(
    item_id number primary key,name_ varchar2(20),prize number,category varchar(15)
);
create table order_
(
    o_id number primary key,item_id number references menu(item_id),table_no number,qty number
);
null {
  id: '<20210131061943.1.38913E890028320C@DOMAIN.com>',message: 'Queued. Thank you.'
}

错误是打击

sql> declare
  2      cursor data1 is  select max(prize) as "prize_",category
  3                       from menu
  4                       group by category;
  5
  6      cursor data2(pr number,cat varchar(15)) is
  7          select prize,name_,category
  8          from menu
  9          where prize = pr and category = cat;
 10
 11
 12      data1_cat varchar(15);
 13      data1_pri number;
 14
 15      data2_cat varchar(15);
 16      data2_pri number;
 17      data2_name varchar(15);
 18  begin
 19      open data1;
 20      open data2;
 21
 22      fetch data1 into data1_pri,data1_cat;
 23      while data1%found
 24      loop
 25          fetch data2(data1_pri,data1_cat) into data2_pri,data2_name,data2_cat;
 26          while data2%found
 27          loop
 28              dbms_output.put_line(data2_name || ' '  || data2_pri || ' '  || data2_cat);
 29              fetch data2(data1_pri,data2_cat;
 30          end loop;
 31
 32
 33          fetch data1 into data1_pri,data1_cat;
 34      end loop;
 35      close data2;
 36      close data1;
 37  end;
 38  /

解决方法

所以你的匿名块有太多的混乱。 ORA-06550 不是你的问题,PLS-00103 和 ORA-06550 一起标志着你搞砸了代码的地方。

首先,您的游标声明不符合 documentation 中的语法方案。 cursor data2(pr number,cat varchar(15)) 应该是 cursor data2(pr number,cat varchar),注意你的第一个错误是如何说 ORA-06550: line 6,column 40: PLS-00103: Encountered the symbol "(" when expecting one of the following: := . ),@ % default character,因为在第 6 行它遇到了 ( 作为 varchar(15) 的一部分,它不应该在那里.

您的光标处理无处不在。游标参数是在打开游标而不是在获取游标时提供的,而且您在循环外打开和关闭游标 data2 这意味着在获取时不会更改循环中的数据。正如我之前提到的,获取语法是完全错误的,在获取数据时没有向游标提供参数。这一切都可以解决,但我想提出一个更简洁、更简单的替代方法来调用你的游标(除非你必须在你的任务中使用 open、fetch、close):

declare
    cursor data1 is  select max(prize) as "prize_",category
                     from menu
                     group by category;
    cursor data2(pr number,cat varchar) is
        select prize,name_,category
        from menu
        where prize = pr and category = cat;
begin
    for c in data1 loop
        for i in data2(c."prize_",c.category) loop
            dbms_output.put_line(i.name_ || ' '  || i.prize || ' '  || i.category);
        end loop;
    end loop;
end;
/

这是原始代码的固定游标用法,我建议您阅读更多游标,例如 here,我添加了注释以更好地了解代码中发生的情况:

declare
    cursor data1 is  select max(prize) as "prize_",category
        from menu
        where prize = pr and category = cat;
    data1_cat varchar(15);
    data1_pri number;
    data2_cat varchar(15);
    data2_pri number;
    data2_name varchar(15);
begin
    -- Open cursor data1 and start looping over data in cursor
    open data1;
    loop
        -- Fetch cursor data1 values into variables
        fetch data1 into data1_pri,data1_cat;
        -- Check if cursor provided data,if not exit loop
        exit when data1%notfound;
        -- Open cursor data2 with parameters from variables filled with data from cursor data1 and start looping over data in cursor
        open data2(data1_pri,data1_cat);
        loop
            -- Fetch cursor data2 values into variables
            fetch data2 into data2_pri,data2_name,data2_cat;
            -- Check if cursor provided data,if not exit loop
            exit when data2%notfound;
            -- Handle variables as needed
            dbms_output.put_line(data2_name || ' '  || data2_pri || ' '  || data2_cat);
        end loop;
        -- Close cursor data2 as new cursor will be opened in next loop and without closing it would lead to ORA-06511: PL/SQL: cursor already open
        close data2;
    end loop;
    -- Close cursor data1 as good practice and possibly to avoid ORA-01000: maximum open cursors exceeded
    close data1;
end;
/

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...