如何在sql(oracle)中将Listag与UDT一起使用?

如何在sql(oracle)中将Listag与UDT一起使用?,sql,oracle,user-defined-types,listagg,Sql,Oracle,User Defined Types,Listagg,LISTAGG函数似乎不适用于UDT,如何克服这个问题 首先,看看我的sql: create or replace type objtype as object( id int, col1 varchar2(30), col2 float ); create table myTab( col1 objtype ); insert into myTab values (objtype(1,'col1',10)); insert into myTab values

LISTAGG函数似乎不适用于UDT,如何克服这个问题

首先,看看我的sql:

create or replace type objtype as object(
    id int,
    col1 varchar2(30),
    col2 float
);

create table myTab(
    col1 objtype
);

insert into myTab values (objtype(1,'col1',10));
insert into myTab values (objtype(2,'col2',20));
insert into myTab values (objtype(3,'col3',3000));

select listagg(t.col1,', ') within group (order by 1) from myTab t;
我想在一行中显示表中的每个元素,如下所示:

objtype(1,'col1',10) , objtype(2,'col2',20), objtype(3,'col3',3000)
但是我得到了这个错误:

默契德勒-

Erreur SQL:ORA-00932:不一致的数据类型:预期数量Get USER.OBJTYPE

  • 00000-“不一致的数据类型:应为%s获得%s”
  • 我应该使用另一个函数吗?那是什么


    感谢您的回复。

    要在UDT中使用listagg,您需要以某种方式序列化数据。 在我看来,您可以按照以下步骤从对象生成一个XMLType,然后在XML对象上使用getStringVal()函数,或者向对象添加一个toString成员函数

    例如:

    select listagg(xmltype(t.col1).getStringVal(),', ') within group (order by 1) from myTab t;
    ..... 
    <OBJTYPE><ID>1</ID><COL1>col1</COL1><COL2>10</COL2></OBJTYPE>, <OBJTYPE><ID>2</ID><COL1>col2</COL1><COL2>20</COL2></OBJTYPE>, <OBJTYPE><ID>3</ID><COL1>col3</COL1><COL2>3000</COL2></OBJTYPE>
    
    1) 添加函数以生成对象的“文本”表示

    create or replace type objtype as object(
        id int,
        col1 varchar2(30),
        col2 float,
        member function toStr return varchar2
    );
    
    create or replace type body objtype is
        member function toStr return varchar2 is 
        begin 
          return 'objtype('||self.id||','||col1||','||col2||')';
        end;
    end;
    
    select listagg(t.col1.toStr(),', ') within group (order by 1) from myTab t;
    
    2) -复杂而强大

    ImpAggr正在实现自定义聚合机制

    create  or replace type  ImpAggr as object(
      list_of_object varchar2(32000), -- second highest value seen so far
      static function ODCIAggregateInitialize(sctx IN OUT ImpAggr) 
        return number,
      member function ODCIAggregateIterate(self IN OUT ImpAggr, 
        value IN objtype) return number,
      member function ODCIAggregateTerminate(self IN ImpAggr, 
        returnValue OUT varchar2, flags IN number) return number,
      member function ODCIAggregateMerge(self IN OUT ImpAggr, 
        ctx2 IN ImpAggr) return number
    );
    /
    
    create or replace type body ImpAggr is 
    static function ODCIAggregateInitialize(sctx IN OUT ImpAggr) 
    return number is 
    begin
    
       -- Aggregate Initialize
      sctx := ImpAggr(null);
      return ODCIConst.Success;
    end;
    
    member function ODCIAggregateIterate(self IN OUT ImpAggr, value IN objtype) return number is
    begin
      -- Aggregate Iterate
    
      self.list_of_object :=list_of_object || ',objtype('||value.id||','||value.col1||','||value.col2||')';
    
      return ODCIConst.Success;
    end;
    
    member function ODCIAggregateTerminate(self IN ImpAggr, 
        returnValue OUT varchar2, flags IN number) return number is
    begin
      -- retrun result list_of_object.
      returnValue := self.list_of_object;
      return ODCIConst.Success;
    end;
    
    member function ODCIAggregateMerge(self IN OUT ImpAggr, ctx2 IN ImpAggr) return number is
    begin 
      -- merge content only if aggregation process gone in parallel execution
      self.list_of_object := ','||ctx2.list_of_object;
      return ODCIConst.Success;
    end;
    end;
    /
    
    创建聚合函数

    CREATE FUNCTION CustomAggregation (input objtype) RETURN varchar2 
    PARALLEL_ENABLE AGGREGATE USING ImpAggr;
    
    和用法

    select CustomAggregation(t.col1) from myTab t;
    

    您的集合没有自然的字符串表示形式——尽管您的客户机可能会在查询表时显示类似于您所看到的多行的内容。如果是这样,客户就是这样解释对象的;该表示在DB中不可用,因此listagg无法使用它。如果可以创建一个匹配的集合类型,则可能获得的最接近对象集合;然后它的显示仍将取决于您的客户端。
    select CustomAggregation(t.col1) from myTab t;