截断的LISTAGG字符串

How*_*wie 9 sql oracle aggregate-functions oracle11g oracle11gr2

我正在使用Oracle 11g r2,我需要从多行连接字符串(VARCHAR2,300).我正在使用LISTAGG哪个工作很好,直到连接的字符串达到限制.那时我收到了一个ORA-01489: result of string concatenation is too long.

最后,我只想要串联字符串的前4000个字符.我如何到达并不重要.我会接受效率低下的解决方案.

这是我的查询:

SELECT LISTAGG(T.NAME, ' ') WITHIN GROUP (ORDER BY NULL)
FROM T
Run Code Online (Sandbox Code Playgroud)

Fra*_*itt 3

您可以使用内置(但已弃用)STRAGG 函数

    select sys.stragg(distinct name) from t
Run Code Online (Sandbox Code Playgroud)

(请注意,不同似乎是避免重复所必需的)

或定义您自己的聚合函数/类型:

CREATE OR REPLACE TYPE "STRING_AGG_TYPE" as object
(
  total varchar2(4000),

  static function ODCIAggregateInitialize(sctx IN OUT string_agg_type) return number,

  member function ODCIAggregateIterate(self  IN OUT string_agg_type,
                                       value IN varchar2) return number,

  member function ODCIAggregateTerminate(self        IN string_agg_type,
                                         returnValue OUT varchar2,
                                         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 varchar2) return number is
  begin
    -- prevent buffer overflow for more than 4,000 characters
    if nvl(length(self.total),
           0) + nvl(length(value),
                    0) < 4000 then
      self.total := self.total || ';' || value;
    end if;
    return ODCIConst.Success;
  end;

  member function ODCIAggregateTerminate(self        IN string_agg_type,
                                         returnValue OUT varchar2,
                                         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 := self.total || ctx2.total;
    return ODCIConst.Success;
  end;

end;

CREATE OR REPLACE FUNCTION stragg(input varchar2 )
   RETURN varchar2
   PARALLEL_ENABLE AGGREGATE USING string_agg_type;
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

select STRAGG(name) from t
Run Code Online (Sandbox Code Playgroud)

我相信这种方法最初是由 Tom Kyte 提出的(至少,我是从那里得到的 - Asktom: StringAgg