如何在Java中实现Oracle用户定义的聚合函数

3
Oracle手册所述,

通过实现一组称为ODCIAggregate例程的例程集,可以创建用户定义的聚合函数。你可以将这些例程作为对象类型中的方法实现,因此实现可以使用Oracle支持的任何语言,如PL / SQL、C、C++或Java

没有其他信息说明如何实现它。我找到了一个在C/C++中实现的示例。
有人知道如何使用Java完成此操作吗?任何信息都会很棒。

1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Bob Jarvis - Слава Україні
请参考这个答案:http://stackoverflow.com/questions/38217040/need-help-for-performing-below-calculation/38219279#38219279 那里有一个用户自定义的聚合函数示例。 - krokodilko
显然,Java实现聚合函数并不是很常见的方法(根据回答的数量和延迟)。无论如何,可以在此处找到一个可靠的示例:http://dbprism.cvs.sourceforge.net/viewvc/dbprism/odi/db/CreateAggregateFunction.sql?revision=1.1.1.1&view=markup - Marmite Bomber
1个回答

2
是的,Java实现Oracle聚合函数确实是可能的。 启用的技巧不是使用 ORACLE TYPE 的Java实现, 而是在Java类上方定义一个PL / SQL包装器包,并在TYPE实现中使用PL / SQL函数。
以下是基于Java的“Hello World”聚合函数的非常简单的实现 - 聚合函数始终返回一个字符串“Hello World”。
Java类几乎什么都没有做,只在ODCITerminate函数中返回字符串“Hello World”。
任何基于Java的聚合函数的实际实现都需要设置上下文类并将其传递给每个迭代方法。
Java类
Create or Replace AND RESOLVE Java Source Named "JAggrFun" As
import java.math.BigDecimal;

class JAggrFun {
/*
Supporting Java class for dummy aggregate function
Implemented methods:
initiate   - dummy
iterate    - dummy
terminate  - return "Hello World"
merge (is not required)

*/
  final static BigDecimal SUCCESS = new BigDecimal(0);
  final static BigDecimal ERROR = new BigDecimal(1);

  static public BigDecimal ODCIInitialize(BigDecimal[] sctx) {

    return SUCCESS; 
  }

  static public BigDecimal ODCIIterate(BigDecimal ctx, String str) { 

     return SUCCESS;                                                                 
  } 

  static public BigDecimal ODCITerminate(BigDecimal ctx, String[] str) {

    str[0] = "Hello World";
    return SUCCESS;
  } 

}
/

Java方法的包装器包。
create or replace
PACKAGE JAggrFunPackage authid current_user AS
  FUNCTION ODCIInitialize(
                  ctx OUT NOCOPY NUMBER
                  ) RETURN NUMBER
                  AS LANGUAGE JAVA
    NAME 'JAggrFun.ODCIInitialize(
              java.math.BigDecimal[]) return java.math.BigDecimal';

  FUNCTION ODCIIterate(
                  ctx IN NUMBER,
                  str VARCHAR2) RETURN NUMBER
                  AS LANGUAGE JAVA
    NAME 'JAggrFun.ODCIIterate(
              java.math.BigDecimal,
              java.lang.String) return java.math.BigDecimal';

  FUNCTION ODCITerminate(
                  ctx IN NUMBER,
                  str OUT VARCHAR2) RETURN NUMBER
                  AS LANGUAGE JAVA
    NAME 'JAggrFun.ODCITerminate(
              java.math.BigDecimal,
              java.lang.String[]) return java.math.BigDecimal';

END JAggrFunPackage;
/

类型

CREATE OR REPLACE 
TYPE JAggrFunPackageType authid current_user AS OBJECT
  (  
   jctx NUMBER, -- stored context;  not used in dummy implementation
   STATIC FUNCTION
        ODCIAggregateInitialize(sctx IN OUT NOCOPY JAggrFunPackageType )
        RETURN NUMBER,

   MEMBER FUNCTION
        ODCIAggregateIterate(self IN OUT NOCOPY JAggrFunPackageType,
                             VALUE IN VARCHAR2 )
        RETURN NUMBER,

   MEMBER FUNCTION
        ODCIAggregateTerminate(self IN JAggrFunPackageType,
                               returnValue OUT NOCOPY VARCHAR2,
                               flags IN NUMBER)
        RETURN NUMBER, 

   MEMBER FUNCTION
        ODCIAggregateMerge(self IN OUT NOCOPY JAggrFunPackageType,
                           ctx IN JAggrFunPackageType)
        RETURN NUMBER
);
/

Aggregate Function

CREATE OR REPLACE 
FUNCTION JAggr(input VARCHAR2 )
RETURN VARCHAR2
AGGREGATE USING JAggrFunPackageType;
/

类型定义

create or replace
type body JAggrFunPackageType  is
  static function ODCIAggregateInitialize(sctx IN OUT NOCOPY JAggrFunPackageType)
  return number
  is
  begin
    sctx := JAggrFunPackageType( null );
    return ODCIConst.Success;
  end;

  member function ODCIAggregateIterate(self IN OUT NOCOPY JAggrFunPackageType,
                                       value IN varchar2 )
  return number
  is
     status  NUMBER;
  begin
    if self.jctx is null then

      status := JAggrFunPackage.ODCIInitialize(self.jctx);
      if (status <> ODCIConst.Success) then
         return status;
      end if;
    end if;

    status := JAggrFunPackage.ODCIIterate(jctx,value);

    return status;
  end;

  member function ODCIAggregateTerminate(self IN JAggrFunPackageType,
                                         returnValue OUT NOCOPY VARCHAR2,
                                         flags IN number)
  return number
  is
  begin

    return JAggrFunPackage.ODCITerminate(jctx, returnValue);
  end;

  member function  ODCIAggregateMerge(self IN OUT NOCOPY JAggrFunPackageType,
                           ctx IN JAggrFunPackageType)
  return number
  is
  begin
    return ODCIConst.Success;
  end;
end;
/

测试

select JAggr(dummy) from dual;

JAGGR(DUMMY)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
-------------
Hello World 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接