2010-11-30 95 views
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], [], [], [], [], [], [], [], [], [], [], [] 

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

+1

'ORA-00600'通常表示一个Oracle错误 - 有时是由于功能的意外组合。你运行的是什么确切的Oracle版本? – 2010-11-30 04:16:43

+0

我正在使用Oracle 11g第2版(11.2.0.1.0)。 – wcmatthysen 2010-11-30 06:40:14

回答

7

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

是否在包计数中包含一个自定义聚合函数为“非常不寻常”?不确定。当然,我们允许在PL/SQL函数中包含数据盒式功能。但用户定义的聚合是ODCI的特例。尽管文档没有明确的规定,但所有示例都使用CREATE FUNCTION来实现聚合。

那么,该怎么办?那么,ORA-00600消息需要Oracle支持人员的介入,因为它需要一个补丁。如果您有支持帐户,您可以find out more about this particular issue here。您需要提出iTAR以获得进一步的解决方案。否则恐怕你可能不幸运。