3

我正在尝试在 Oracle 中编写一个自定义聚合函数,并将该函数与我拥有的其他一些函数一起分组到一个包中。作为一个例子(模拟我遇到的问题)假设我的自定义聚合来做一个数字的总和看起来像:

CREATE OR REPLACE TYPE SUM_AGGREGATOR_TYPE AS OBJECT (
    summation NUMBER,

    STATIC FUNCTION ODCIAggregateInitialize(agg_context IN OUT
       SUM_AGGREGATOR_TYPE) RETURN NUMBER,

    MEMBER FUNCTION ODCIAggregateIterate(self IN OUT SUM_AGGREGATOR_TYPE,
        next_number IN NUMBER) RETURN NUMBER,

    MEMBER FUNCTION ODCIAggregateMerge(self IN OUT SUM_AGGREGATOR_TYPE,
        para_context IN SUM_AGGREGATOR_TYPE) RETURN NUMBER,

    MEMBER FUNCTION ODCIAggregateTerminate(self IN SUM_AGGREGATOR_TYPE,
        return_value OUT NUMBER, flags IN NUMBER) RETURN NUMBER
);

CREATE OR REPLACE TYPE BODY SUM_AGGREGATOR_TYPE IS

  STATIC FUNCTION ODCIAggregateInitialize(agg_context IN OUT
    SUM_AGGREGATOR_TYPE)
      RETURN NUMBER IS
  BEGIN
    agg_context := SUM_AGGREGATOR_TYPE(NULL);
    RETURN ODCIConst.Success;
  END;


  MEMBER FUNCTION ODCIAggregateIterate(self IN OUT SUM_AGGREGATOR_TYPE,
    next_number IN NUMBER)
      RETURN NUMBER IS
  BEGIN
    IF self.summation IS NULL THEN
        self.summation := next_number;
    ELSIF summation IS NOT NULL THEN
        self.summation := self.summation + next_number;
    END IF;
    RETURN ODCIConst.Success;
  END;

  MEMBER FUNCTION ODCIAggregateMerge(self IN OUT SUM_AGGREGATOR_TYPE,
    para_context IN SUM_AGGREGATOR_TYPE)
      RETURN NUMBER IS
  BEGIN
    self.summation := self.summation + para_context.summation;
    RETURN ODCIConst.Success;
  END;

  MEMBER FUNCTION ODCIAggregateTerminate(self IN SUM_AGGREGATOR_TYPE,
    return_value OUT NUMBER, flags IN NUMBER)
      RETURN NUMBER IS
  BEGIN
    return_value := self.summation;
    return ODCIConst.Success;
  END;

END;

如果我编写以下函数定义:

CREATE OR REPLACE FUNCTION MY_SUM(input NUMBER)
  RETURN NUMBER PARALLEL_ENABLE AGGREGATE USING SUM_AGGREGATOR_TYPE;

和相应的类型声明来测试:

CREATE OR REPLACE TYPE VECTOR
IS
  TABLE OF NUMBER;

这个说法:

select my_sum(column_value) from table(vector(1, 2, 1, 45, 22, -1));

给出 70 的正确结果。但是,使用函数定义创建一个包:

CREATE OR REPLACE PACKAGE MY_FUNCTIONS AS
  FUNCTION MY_SUM(input NUMBER)
    RETURN NUMBER PARALLEL_ENABLE AGGREGATE USING SUM_AGGREGATOR_TYPE;
END;

并通过以下方式调用它:

select MY_FUNCTIONS.my_sum(column_value) from table(vector(1, 2, 1, 45, 22, -1));

爆炸

ORA-00600: internal error code, arguments: [17090], [], [], [], [], [], [], [], [], [], [], [] 

是否可以在包声明中嵌套自定义聚合函数?

4

1 回答 1

7

Oracle 使用 ORA-00600 来表示未处理的异常,即错误。第一个参数表示异常;ORA-17090 是一个通用的“不允许的操作”。它们经常受限于数据库版本和操作系统平台的特定排列。其他时候,这只是意味着我们正在做一些非常不寻常的事情。

在包中包含自定义聚合函数是否算“非常不寻常”?没有把握。当然,我们被允许在 PL/SQL 函数中包含数据磁带函数。但是用户定义的聚合是 ODCI 的一个特例。虽然文档没有针对包的明确规则,但所有示例都使用CREATE FUNCTION.

那么该怎么办?好吧,ORA-00600 消息需要 Oracle Support 的干预,因为它需要一个补丁。如果您有支持帐户,您可以在此处找到有关此特定问题的更多信息。您需要提出 iTAR 以获得进一步的解决方案。否则我恐怕你很不走运。

于 2010-11-30T05:30:46.833 回答