【问题标题】:How to populate nested table (with nested objects) by using cursor and bulk collect如何使用游标和批量收集填充嵌套表(带有嵌套对象)
【发布时间】:2019-01-04 00:02:45
【问题描述】:

也许你知道问题出在哪里。

我有 3 种类型:

create or replace type t_money as object (
  val number(14,2)
 ,cur varchar2(3 CHAR)
);
/

create or replace type t_wallet as object (
  name   varchar2(50 CHAR)
 ,amount t_money
);
/

create or replace type t_wallets is table of t_wallet;
/

我需要使用批量收集从游标填充嵌套表:

declare
  walletCollection t_wallets;
  cursor walletCursor is 
    select 'some name'          as name
          ,t_money(99, 'EUR')   as amount
      from dual;
begin
  open walletCursor;
  fetch walletCursor bulk collect into walletCollection;
  close walletCursor;
end;

Aaaaaaand ...它不起作用。我收到此错误:

ORA-06550: line 9, column 40: PLS-00386: type mismatch found at 'WALLETCOLLECTION' between FETCH cursor and INTO variables

我知道我可以使用:

type walletRecords is table of walletCursor%ROWTYPE;
walletCollection walletRecords;

但在这种情况下我不能这样做,并且 walletCollection 必须是 t_wallets 的嵌套表。

如何做到这一点?哪里错了?

Oracle 实时脚本 https://livesql.oracle.com/apex/livesql/s/hr22zxdw7842um41u9ylnraz1

【问题讨论】:

    标签: oracle plsql type-mismatch


    【解决方案1】:

    不匹配很明显:您的光标位于一组具有两列的行上,类型分别为VARCHAR2T_MONEY,但嵌套表需要T_WALLET 类型的对象。不知何故,您必须从游标中的数据构造T_WALLET 类型的对象。

    假设您的游标定义中的SELECT 语句模拟具有两列的实际表,您可以将其包装在使用构造函数的外部查询中。 (否则表或SELECT 语句必须已经存储或创建T_WALLETs。)

    declare
      walletCollection t_wallets;
      cursor walletCursor is
        select t_wallet(name, amount)   -- THIS outer select, using the constructor
        from   (
                 select 'some name'          as name
                      , t_money(99, 'EUR')   as amount
                 from   dual
               );
    begin
      open walletCursor;
      fetch walletCursor bulk collect into walletCollection;
      close walletCursor;
    end;
    /
    

    这是一个简短的演示,显示嵌套表已正确填充。注意程序主体中对dbms_output.put_line 的调用;通常,您只会出于开发和调试目的(以及为了说明,如本例)而做这样的事情。确保您运行 set serveroutput on 以查看输出。

    declare
      walletCollection t_wallets;
      cursor walletCursor is
        select t_wallet(name, amount) 
        from   (
                 select 'some name'          as name
                      , t_money(99, 'EUR')   as amount
                 from   dual
               );
    begin
      open walletCursor;
      fetch walletCursor bulk collect into walletCollection;
      close walletCursor;
    
      for i in 1 .. walletCollection.Count loop
        dbms_output.put_line( 'Name: '       || walletCollection(i).name       || 
                              ', amount: '   || walletCollection(i).amount.val ||
                              ', currency: ' || walletCollection(i).amount.cur );
      end loop;
    end;
    /
    
    Name: some name, amount: 99, currency: EUR
    
    
    PL/SQL procedure successfully completed.
    

    【讨论】:

      猜你喜欢
      • 2017-10-03
      • 1970-01-01
      • 1970-01-01
      • 2014-10-31
      • 1970-01-01
      • 1970-01-01
      • 2014-12-03
      • 1970-01-01
      • 2015-09-16
      相关资源
      最近更新 更多