【问题标题】:How to assign values of object type attributes to different object type with same attribute properties in plsql?如何在plsql中将对象类型属性的值分配给具有相同属性属性的不同对象类型?
【发布时间】:2020-10-18 15:06:19
【问题描述】:

我有两种具有相同属性的不同类型。我需要将第一种类型的属性值分配给其他类型。除了架构和对象名称之外,它们完全相同。

CREATE OR REPLACE TYPE SCHEMA_A.type_A AS OBJECT(XCOL VARCHAR2(80), YCOL VARCHAR2(80), ZCOL CHAR(2));

CREATE OR REPLACE TYPE SCHEMA_B.type_B AS OBJECT(XCOL VARCHAR2(80), YCOL VARCHAR2(80), ZCOL CHAR(2));

我可以像下面这样一个一个地手动赋值,但实际上有超过 80 个属性。有没有更优雅的方式来达到同样的效果?

SCHEMA_A.type_A.XCOL := SCHEMA_B.type_B.XCOL;
SCHEMA_A.type_A.YCOL := SCHEMA_B.type_B.YCOL;
...

【问题讨论】:

    标签: plsql plsqldeveloper oracle19c object-type


    【解决方案1】:

    AFAIK 您几乎被逐个属性分配所困扰。这是创建 2 种相同类型的副产品 - 这是您的主要错误。但有两种可能的解决方案:

    1. 创建一个只有 1 种类型的通用架构,然后更新引用 到通用架构。
    2. 编写一个函数,将这两种类型作为参数,源和 目的地,并进行逐个属性的复制。你的代码 然后只需调用该函数。

    【讨论】:

      【解决方案2】:

      正如他在回答 @Belayer 中提到的,最好的解决方案是为这两种方案创建一个通用数据类型。


      快速而肮脏的解决方案是使用 SQL 查询进行转换。查看以下可重现的示例:

      create or replace type A.objA as object (attr1 varchar2 (8), attr2 int, attr3 date)
      /
      create or replace type B.objB as object (attr1 varchar2 (8), attr2 int, attr3 date);
      /
      create or replace type A.objtA as table of A.objA;
      /
      create or replace type A.objtB as table of B.objB;
      /
      var rc refcursor 
      declare 
          a A.objA;  
          b B.objB := B.objB ('name B', 1, trunc (sysdate));
          function cast (o B.objB) return A.objA is
              t A.objtA;
          begin
              select cast (multiset (select * from A.objtB (b)) 
                       as A.objtA) into t from dual; 
              return t(1);
          end;
      begin 
          a := cast (b);
          open :rc for select a a from dual;
      end;
      /
      
      A(ATTR1, ATTR2, ATTR3)
      ------------------------------------------------
      OBJA('name B', 1, '2020-10-18 00:00:00')
      

      【讨论】:

        【解决方案3】:

        由于类型是模式对象,它们具有可以稍微简化分配的默认构造函数:

        declare
            v_type_a type_a := type_a('a', 'a', 'a');
            v_type_b type_b := type_b('b', 'b', 'b');
        begin
            v_type_a := type_a(v_type_b.xcol, v_type_b.ycol, v_type_b.zcol);
        end;
        /
        

        在 18c 及更高版本中,由于新的限定表达式功能,同样的想法甚至适用于 PL/SQL-only 类型。

        如果只有两种类型,那么上面的快捷方式可能是您最好的选择。如果您有多组需要分配的类型,请告诉我们;在这种情况下,可能值得花费额外的精力来使用 ANYDATA 构建解决方案,或者使用数据字典来动态构建函数。

        【讨论】:

          猜你喜欢
          • 2020-05-22
          • 2021-06-22
          • 2021-11-21
          • 1970-01-01
          • 1970-01-01
          • 2018-11-03
          • 1970-01-01
          • 1970-01-01
          • 2022-01-15
          相关资源
          最近更新 更多