1

我正在尝试使用以下查询创建一个表:

select base.Col1, base.dt_date,acct.Col2,acct.col3, listagg (acct.e_indic,',') within group (order by acct.e_indic)  as e_indic 
  from tab1 base,
(select dt_date, act, sum(Col4) sets from tab2 group by dt_date, act having sum(Col4) > 0) pos,
tab3 acct
where  base.Col1=acct.Col1 and acct.act=pos.act and base.dt_date >= to_Date('20180601','YYYYMMDD') and
        base.dt_date=pos.dt_date group by base.Col1, base.dt_date,acct.Col2,acct.col3;

我收到错误

ORA-01489: 字符串连接的结果太长。

我已经尝试过堆栈溢出中提供的解决方案,但它不起作用。我的数据库是 exadata。那么我能做些什么来解决这个问题呢?

4

2 回答 2

0

您可以使用自己创建的聚合函数stragg来生成由逗号分隔的 CLOB 类型列表:

create or replace type string_agg_type as object
(
  total CLOB,
  static function ODCIAggregateInitialize(sctx IN OUT string_agg_type)
    return number,
  member function ODCIAggregateIterate(self  IN OUT string_agg_type,
                                       value IN CLOB) return number,
  member function ODCIAggregateTerminate(self        IN string_agg_type,
                                         returnValue OUT CLOB,
                                         flags       IN number)
    return number,
  member function ODCIAggregateMerge(self IN OUT string_agg_type,
                                     ctx2 IN string_agg_type) return number
)
/
create or replace type body string_agg_type is

  static function odciaggregateinitialize(sctx IN OUT string_agg_type)
    return number is
  begin
    sctx := string_agg_type(null);
    return odciconst.success;
  end;
  member function odciaggregateiterate(self  IN OUT string_agg_type,
                                       value IN CLOB) return number is
  begin
    self.total := CONCAT(CONCAT(self.total, to_clob(',')), value);
    return odciconst.success;
  end;
  member function odciaggregateterminate(self        IN string_agg_type,
                                         returnvalue OUT CLOB,
                                         flags       IN number) return number is
  begin
    returnvalue := ltrim(self.total, ',');
    return odciconst.success;
  end;
  member function odciaggregatemerge(self IN OUT string_agg_type,
                                     ctx2 IN string_agg_type) return number is
  begin
    self.total := CONCAT(self.total , ctx2.total);
    return odciconst.success;
  end;
end;
/
CREATE OR REPLACE FUNCTION stragg(input varchar2) RETURN CLOB
  PARALLEL_ENABLE
  AGGREGATE USING string_agg_type;
/  

使用:

select stragg('test string') over (partition by 1 order by 1)
  from dual
connect by level < 10000;
于 2021-02-24T12:08:39.993 回答
0

切换到XMLAGG,它没有那个限制。

  SELECT base.Col1,
         base.dt_date,
         acct.Col2,
         acct.col3,
         --
         -- LISTAGG (acct.e_indic, ',') WITHIN GROUP (ORDER BY acct.e_indic) AS e_indic
         --
         RTRIM (
            XMLAGG (XMLELEMENT (e, acct.e_indic || ', ') ORDER BY acct.e_indic).EXTRACT (
               '//text()'),
            ', ') AS e_indic
    FROM tab1 base,
         (  SELECT dt_date, act, SUM (Col4) sets
              FROM tab2
          GROUP BY dt_date, act
            HAVING SUM (Col4) > 0) pos,
         tab3 acct
   WHERE     base.Col1 = acct.Col1
         AND acct.act = pos.act
         AND base.dt_date >= TO_DATE ('20180601', 'YYYYMMDD')
         AND base.dt_date = pos.dt_date
GROUP BY base.Col1,
         base.dt_date,
         acct.Col2,
         acct.col3;
于 2021-02-24T07:56:57.540 回答