如何在plsql中将具有相同属性属性的对象类型属性值分配给不同的对象类型?

时间:2020-10-18 15:06:19

标签: plsql plsqldeveloper oracle19c object-type

我有两种具有相同属性的不同类型。我需要将第一种类型的属性的值分配给其他类型。它们与模式和对象名称完全相同。

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;
...

3 个答案:

答案 0 :(得分:2)

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

  1. 仅创建一种类型的通用模式,然后更新引用 到通用模式。
  2. 编写一个函数,将两种类型作为参数,分别是source和 目标,并按属性进行复制。您的密码 然后只需调用该函数即可。

答案 1 :(得分: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')

答案 2 :(得分:1)

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

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类型也可以使用相同的想法。

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