-2

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

问题:显示最昂贵项目的类别明智奖

创建表格菜单
(
    item_id 编号主键,
    name_varchar2(20),
    奖品号码,
    类 varchar(15)
);
创建表顺序_
(
    o_id 编号主键,
    item_id 编号参考菜单(item_id),
    table_no 编号,
    数量
);
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, data1_cat) into data2_pri, data2_name, 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  /

错误是打击

ERROR at line 6:
ORA-06550: line 6, column 40:
PLS-00103: Encountered the symbol "(" when expecting one of the following:
:= . ) , @ % default character
The symbol ":=" was substituted for "(" to continue.
ORA-06550: line 25, column 20:
PLS-00103: Encountered the symbol "(" when expecting one of the following:
. into bulk
ORA-06550: line 25, column 80:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
. ( , % from
ORA-06550: line 29, column 24:
PLS-00103: Encountered the symbol "(" when expecting one of the following:
. into bulk
ORA-06550: line 29, column 84:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
. ( , % from
ORA-06550: line 35, column 5:
PLS-00103: Encountered the symbol "CLOSE" when expecting one of the following:
end not pragma final instantiable order overriding static
member constructor map
4

1 回答 1

2

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

首先,您的游标声明不符合文档中的语法方案。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;
/

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

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;
    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;
/
于 2021-01-31T19:36:44.163 回答