初始化架构对象类型与包类型

initializing schema object type vs. package type

我有以下代码:

declare
    type r_rec is record (col1 number, col2 varchar2(10));
    type t_rec is table of r_rec;
    v_rec t_rec := t_rec();
begin

       v_rec.EXTEND(2);
       v_rec(1).col1 := 1;
       v_rec(1).col2 := 'one';

       v_rec(2).col1 := 2;
       v_rec(2).col2 := 'two';

    for i in v_rec.first .. v_rec.last
    loop
        dbms_output.put_line('col1 = ' || v_rec(i).col1 || ', col2 = ' || v_rec(i).col2); 
    end loop;
end;

按预期工作。

我想使用模式对象类型而不是 PLSQL 类型,代码变为:

create or replace type r_rec as object (col1 number, col2 varchar2(10));
/
create or replace type t_rec as table of r_rec;
/

declare
    v_rec t_rec := t_rec();
begin

     v_rec.EXTEND(2);
     v_rec(1).col1 := 1;
     v_rec(1).col2 := 'one';

     v_rec(2).col1 := 2;
     v_rec(2).col2 := 'two';

    for i in v_rec.first .. v_rec.last
    loop
        dbms_output.put_line('col1 = ' || v_rec(i).col1 || ', col2 = ' || v_rec(i).col2); 
    end loop;
end;
/

但是,这次出现了以下错误:

ORA-06533: Subscript beyond count ORA-06512: at line 7 ORA-06512: at "SYS.DBMS_SQL", line 1721

有人能指出我做错了什么吗?

您的第一个代码示例失败 ORA-06533: Subscript beyond count db<>fiddle

要修复它,您需要 EXTEND 集合:

declare
    type r_rec is record (col1 number, col2 varchar2(10));
    type t_rec is table of r_rec;
    v_rec t_rec := t_rec();
begin
    v_rec.EXTEND(2);

    v_rec(1).col1 := 1;
    v_rec(1).col2 := 'one';

    v_rec(2).col1 := 2;
    v_rec(2).col2 := 'two';

    for i in v_rec.first .. v_rec.last
    loop
        dbms_output.put_line('col1 = ' || v_rec(i).col1 || ', col2 = ' || v_rec(i).col2); 
    end loop;
end;
/

你的第二个代码示例有同样的问题;您需要 EXTEND 集合,但您还需要初始化对象:

create or replace type r_rec as object (col1 number, col2 varchar2(10));
create or replace type t_rec as table of r_rec;

declare
    v_rec t_rec := t_rec();
begin
    v_rec.EXTEND(2);
     v_rec(1) := r_rec( 1, 'one' );
     v_rec(2) := r_rec( 2, 'two' );

    for i in v_rec.first .. v_rec.last
    loop
        dbms_output.put_line('col1 = ' || v_rec(i).col1 || ', col2 = ' || v_rec(i).col2); 
    end loop;
end;
/

输出:

col1 = 1, col2 = one
col1 = 2, col2 = two

或者您可以在声明中内联初始化值:

declare
    v_rec t_rec := t_rec( r_rec( 1, 'one' ), r_rec( 2, 'two' ));
begin
    for i in v_rec.first .. v_rec.last
    loop
        dbms_output.put_line('col1 = ' || v_rec(i).col1 || ', col2 = ' || v_rec(i).col2); 
    end loop;
end;
/

db<>fiddle