2010-11-30 172 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以獲得進一步的解決方案。否則恐怕你可能不幸運。