【问题标题】:Trying to write custom aggregation function in Oracle尝试在 Oracle 中编写自定义聚合函数
【发布时间】:2013-08-12 11:58:23
【问题描述】:

基本上,我正在重写一些我已经在互联网和 StackOverflow 上找到的东西。

我的目标是编写一个自定义聚合函数(在 Oracle 中),因为 COLLECT 不够用(我正在处理 4000 个字符以上的非常大的字符串),我对 WM_CONCAT 没有足够的信心,甚至不确定它是否就足够了。

看起来自定义聚合函数是我从嵌套子查询构建 JSON 数据字符串、构建对象的最佳解决方案,因此我需要能够指定值之间的分隔符 - 把这个进入上下文。

我目前的 ORACLE SQL 是这样的:

CREATE OR REPLACE TYPE parms AS TABLE OF CLOB;

CREATE OR REPLACE TYPE string_agg_TYPE AS OBJECT
(
    total CLOB,
    l_delimiter CLOB,

    STATIC FUNCTION
        ODCIAggregateInitialize(sctx IN OUT string_agg_TYPE )
        RETURN NUMBER,

    MEMBER FUNCTION
        ODCIAggregateIterate(self IN OUT string_agg_TYPE ,
                           value IN parms )
        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 parms )
RETURN NUMBER
IS
BEGIN
    IF (value.count = 2)
    THEN
        self.l_delimiter := value(2);
ELSE
  self.l_delimiter := ',';
    END IF;
    self.total := self.total || self.l_delimiter || value(1);
    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,self.l_delimiter);
    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;

当我尝试编译正文定义时,Oracle 给了我以下错误:

错误(8,11):PLS-00306:调用“STRING_AGG_TYPE”时参数的数量或类型错误

那么,我遗漏了什么明显的东西?

感谢您的建议,如果提供的话。

【问题讨论】:

    标签: string oracle aggregate collect


    【解决方案1】:

    对象类型string_agg_TYPE有两个属性:totall_delimiter,顺便说一下,后者没有理由是CLOB数据类型,所以,初始化那个对象数据类型的实例您应该在构造函数中为这些属性传入两个初始化值:

    sctx := string_agg_TYPE(NULL, NULL);
    

    【讨论】:

    • 有趣的是,我刚刚发现了这一点。还是谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 2021-09-07
    • 2019-11-05
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    相关资源
    最近更新 更多