Custom aggregate function inside a package

半世苍凉 提交于 2019-12-12 09:48:34

问题


I'm trying to write a custom aggregate function in Oracle and group that function inside a package together with some other functions that I have. As an example (to simulate the problem I have) suppose my custom aggregation to do a summation of numbers looks like:

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;

If I write the following function definition:

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

and corresponding type declaration to test:

CREATE OR REPLACE TYPE VECTOR
IS
  TABLE OF NUMBER;

this statement:

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

gives the correct result of 70. However, creating a package with the function definition:

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

and calling it via:

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

explodes with

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

Is it possible to have custom aggregate functions nested inside package declarations?


回答1:


Oracle uses ORA-00600 to signal unhandled exceptions i.e. bugs. The first argument indicates the exception; ORA-17090 is a generic "operation not allowed". Frequently they are restricted to specific permutations of database version and OS platform. Other times it just means we're doing something really unusual.

Does including a custom aggregate function inside a package count as "really unusual"? Not sure. Certainly we are permitted to include data cartridge functions in PL/SQL functions. But user-defined aggregates are a special case of ODCI. While the documentation has no explicit rule against packages all the examples implement the aggregate using CREATE FUNCTION.

So, what to do? Well, ORA-00600 messages require the intervention of Oracle Support, as it needs a patch. If you have a Support account you can find out more about this particular issue here. You will need to raise an iTAR to get further resolution. Otherwise I'm afraid you're probably out of luck.



来源:https://stackoverflow.com/questions/4310232/custom-aggregate-function-inside-a-package

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!