如何在ORACLE中动态完成用户类型的名称?

时间:2017-07-20 13:23:45

标签: oracle

我在PL / SQL数据包中有几个用户定义的类型:

TYPE blk_esta IS RECORD (
   codi_mone  VARCHAR2(1),
   codi_situ  VARCHAR2(1),
   situ_pig   VARCHAR2(1),
   IMPORTE    NUMBER(11,2)    
);

TYPE oper_data_mv_out IS RECORD
(
  bloq_esta  blk_esta,
  bloq_aseg  blk_aseg
);

我有一个带有名称和字段顺序的BBDD。所以我获得了第一个字段的名称,我想动态分配一个值。

select name into field from GFM_MODEL;

我尝试了几件事:

sql:= 'SELECT ''E'' into oper_data.bloq_esta.'||name||' from dual';
execute immediate (sql);

out: ORA-00905: missing keyword

sql :='oper_data.bloq_esta.:b1:=''E''';
execute immediate (slq) using in out oper_data;

out:PLS-00457: expressions have to be of SQL types

知道我怎么能这样做吗?

提前致谢。

编辑:我需要它,因为我的结构比示例大得多,我想在一个包含code_bloqname_bloq等的表中定义结构的模型。当有人需要时添加一个新字段,只需要在表中插入。程序在表中读入新字段,无需修改代码。查看结构:

TYPE oper_data_mv_out IS RECORD
(
  bloq_esta  blk_esta,
  bloq_aseg  blk_aseg,
  bloq_toma  blk_toma,
  lista_bene tabla_bene,
  bloq_plan  blk_plan,
  lista_inte tabla_inte,
  bloq_tari  blk_tari,
  bloq_hist  blk_hist,
  bloq_resc  blk_resc,
  bloq_repr  blk_repr,
  bloq_fide  blk_fide,
  bloq_comu  blk_comu,
  lista_cuen tabla_cuen,
  bloq_cumu  blk_cumu,
  bloq_part  blk_part,
  bloq_esp2  blk_esp2,
  bloq_esp3  blk_esp3,
  bloq_esp4  blk_esp4,
  bloq_esp5  blk_esp5,
  bloq_esp6  blk_esp6,
  bloq_esp7  blk_esp7,
  bloq_esp8  blk_esp8,
  bloq_esp9  blk_esp9,
  bloq_esp10 blk_esp10,
  bloq_esp11 blk_esp11,
  bloq_esp12 blk_esp12,
  lista_blk_camp tabla_blk_camp,
  lista_blk_warn tabla_blk_warn  
);

其他解决方案可以使用其他引用分配数据...而不是oper_data_mv_out.bloq_esta.(1)。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

首先,将打包的(PL / SQL记录)类型重新声明为模式级(SQL对象)类型。

然后你的代码

sql :='oper_data.bloq_esta.:b1:=''E''';
execute immediate (slq) using in out oper_data;

应该有效...稍微修改一下......当然......

sql :='
    declare
        l_oper_data     oper_data_mv_out := :oper_data;
    begin
        l_oper_data.bloq_esta.'||field_name||' := ''E'';
        :oper_data := l_oper_data;
    end;
';
execute immediate sql
    using in out oper_data;

概念验证

首先,架构级别类型......

create or replace type obj_so_variable_field_name
as
object (
    field_1                     varchar2(32),
    field_2                     varchar2(32),
    field_of_corn               varchar2(32),
    field_of_maze               varchar2(32),
    fieldy_of_korn              varchar2(32)
);
/

现在进行动态字段修改......

declare
    l_record                    obj_so_variable_field_name := new obj_so_variable_field_name(null, null, null, null, null);
    l_field_to_change           constant varchar2(30) := 'field_of_corn';
    l_value_to_change           constant varchar2(32) := '42';
begin
    dbms_output.put_line('*** before the change');
    dbms_output.put_line('>'||l_record.field_1);
    dbms_output.put_line('>'||l_record.field_2);
    dbms_output.put_line('>'||l_record.field_of_corn);
    dbms_output.put_line('>'||l_record.field_of_maze);
    dbms_output.put_line('>'||l_record.fieldy_of_korn);

    dbms_output.put_line('*** now changing '||l_field_to_change||' to value of "'||l_value_to_change||'"');
    execute immediate '
        declare
            l_oper_data             obj_so_variable_field_name := :oper_data;
        begin
            l_oper_data.'||l_field_to_change||' := :in_value;
            :oper_data := l_oper_data;
        end;
    ' using
        in out l_record,
        in l_value_to_change
    ;

    dbms_output.put_line('*** after the change');
    dbms_output.put_line('>'||l_record.field_1);
    dbms_output.put_line('>'||l_record.field_2);
    dbms_output.put_line('>'||l_record.field_of_corn);
    dbms_output.put_line('>'||l_record.field_of_maze);
    dbms_output.put_line('>'||l_record.fieldy_of_korn);
end;
/

......在运行时,产生......

*** before the change
>
>
>
>
>
*** now changing field_of_corn to value of "42"
*** after the change
>
>
>42
>
>