【问题标题】:Error in fetching a cursor of table of objects获取对象表游标时出错
【发布时间】:2021-07-07 05:06:21
【问题描述】:

我是学习 PLSQL 的新手,对 PLSQL 中的对象类型(抽象数据类型)绝对是新手。所以无论如何,我在定义游标时看到了我公司使用表运算符的代码,所以我想尝试一下。在以下匿名块中,我收到一个错误 “PLS-00386:在 FETCH 游标和 INTO 变量之间的 'V_CU' 处发现类型不匹配”但是当我在声明 V_CU 时使用 c%rowtype (注释部分)而不是 obj_emp 时,我没有收到该错误。我无法理解这个错误的原因。

毕竟一行光标 c 由对象 obj_emp 的单个元素组成,不是吗?

CREATE OR REPLACE TYPE obj_emp IS OBJECT (
    first_name  VARCHAR2(80),
    last_name   VARCHAR2(80),
    salary      NUMBER
);
/
CREATE OR REPLACE TYPE tab_emp_t IS TABLE OF obj_emp;
/

declare
    v_num number:=60;
    tab_emp tab_emp_t :=tab_emp_t();
    cursor c is select * from table(tab_emp);
    v_cu obj_emp --c%rowtype
    ;
      
begin

    for i in (select * from employees_copy where department_id = v_num) loop
        tab_emp.extend;
        tab_emp(tab_emp.last):=obj_emp(i.first_name, i.LAST_NAME, i.salary);
    end loop;
    
    open c;
    loop
        fetch c into v_cu;
        exit when c%notfound;
        dbms_output.put_line(v_cu.first_name||' '||v_cu.last_name||' earns '||v_cu.salary);
    end loop;
    close c;
end;
/

【问题讨论】:

    标签: arrays oracle plsql


    【解决方案1】:

    预计会出错;如果您取消注释 v_cu 的数据类型,它会被修复 - 它仍然应该是 c%rowtype

    但是,我认为您想尝试的是显示存储到集合中的值。如果是这样,请查看以下代码(稍微修改了您编写的内容;我没有您的表格,所以我使用 Scott 的 EMP 代替)。

    SQL> declare
      2      v_num number:=10;
      3      tab_emp tab_emp_t :=tab_emp_t();
      4      v_cnt number:=1;
      5      cursor c is select * from table(tab_emp);
      6      v_cu c%rowtype; --obj_emp --c%rowtype
      7
      8  begin
      9      dbms_output.put_line('-------- Store values into a collection ---------');
     10      for i in (select * from emp where deptno = v_num) loop
     11          tab_emp.extend;
     12          tab_emp(v_cnt):=obj_emp(i.ename, i.job, i.sal);
     13          v_cnt:=v_cnt+1;
     14      end loop;
     15      v_cnt:=1;
     16
     17      dbms_output.put_line('-------- Display values from a cursor -----------');
     18      open c;
     19      loop
     20          fetch c into v_cu;
     21          exit when c%notfound;
     22          dbms_output.put_line(v_cu.first_name||' '||v_cu.last_name||' earns '||v_cu.salary);
     23      end loop;
     24
     25      dbms_output.put_line('-------- Display values from a collection -------');
     26
     27      for i in tab_emp.first .. tab_emp.last loop
     28        dbms_output.put_Line(tab_emp(i).first_name ||' '|| tab_emp(i).last_name ||' earns ' || tab_emp(i).salary);
     29      end loop;
     30  end;
     31  /
    

    结果

    -------- Store values into a collection ---------
    -------- Display values from a cursor -----------
    CLARK MANAGER earns 2450
    KING PRESIDENT earns 5000
    MILLER CLERK earns 1300
    -------- Display values from a collection -------
    CLARK MANAGER earns 2450
    KING PRESIDENT earns 5000
    MILLER CLERK earns 1300
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    【讨论】:

    • 感谢 Littlefoot 抽出宝贵时间。我只是想正确地从光标中获取并可能显示光标中的值。我仍然没有回答的问题是正确的 v_cu 的类型到底是什么。怎么不是obj_emp?如果 c%rowtype 与 obj_emp 不同,它的类型是什么?
    • V_CU 是一个游标变量,应该接受游标返回的值,所以它的数据类型是 C%ROWTYPE。看看 Steven Feuerstein 的文章,在这里 (blogs.oracle.com/oraclemagazine/working-with-cursors) 了解更多信息和示例。
    • 嗨 Lightfoot,我查看了这篇文章,但我认为您没有得到我的问题。我知道当我将 v_cu 声明为游标 c 的行类型时,它可以正常工作,但是当我将 v_cu 明确声明为 obj_emp 时,它就不起作用了。我的问题是,如果不是 obj_emp,实际上 c%rowtype 的类型是什么?游标是从对象 obj_emp 的集合中选择的,因此假设游标 c 的每一行基本上都是 obj_emp 并没有错,因此将游标 c 的行提取到 obj_emp 的变量实例 v_cu 中并没有错。但可惜我不能那样做!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    • 2021-05-01
    • 2014-05-14
    • 1970-01-01
    相关资源
    最近更新 更多