2010-11-30 21 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; 

この文:

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)); 

爆発

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

は、関数定義でパッケージを作成し、しかし70の正確な結果を与えます

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

カスタム集計関数をパッケージ宣言内にネストすることは可能ですか?

+1

'ORA-00600'は通常、予期しない機能の組み合わせのためにOracleバグを示します。どのようなOracleの正確なバージョンを実行していますか? –

+0

私はOracle 11g Release 2(11.2.0.1.0)を使用しています。 – wcmatthysen

+0

この問題に関するニュースはありますか?私も問題があります。しかし、私の場合、接続は 'ORA-03113:通信チャネル上のファイルの終わり 'に打ち切られます。私はこれが 'ORA-00600'よりもさらに悪いと思う。 'SELECT * FROM ALL_PROCEDURES'をチェックすると、ユーザ定義集計が正しく作成され、登録されていることがわかります... –

答えて

7

OracleはORA-00600を使用して未処理の例外、つまりバグを通知します。最初の引数は例外を示します。 ORA-17090は一般的な「操作が許可されていません」です。頻繁にデータベースバージョンとOSプラットフォームの特定の順列に制限されています。それ以外の時は、本当に珍しい何かをやっているということです。

パッケージ内にカスタム集計関数を含めることは、「本当に珍しい」とカウントされますか?わからない。確かに、PL/SQL関数にデータ・カートリッジ関数を組み込むことは許されています。しかし、ユーザー定義集計はODCIの特殊なケースです。ドキュメントにはパッケージに対する明示的なルールはありませんが、すべての例ではCREATE FUNCTIONを使用して集計が実装されています。

だから、どうしたらいいですか? ORA-00600メッセージには、パッチが必要なためOracle Supportの介入が必要です。サポートアカウントをお持ちの場合はfind out more about this particular issue hereです。あなたはさらなる解決を得るためにiTARを上げる必要があります。そうでなければ、あなたはおそらく運が悪いのではないかと心配しています。

+0

これはサポートされていないと奇妙です。私はオラクルのフォーラムにこれを掲載して、彼らが何を言わなければならないかを見ていきます。 – wcmatthysen

+0

Oracleフォーラムの投稿を作成しました:http://forums.oracle.com/forums/thread.jspa?threadID=2137501&tstart=0これで、Oracleのスタッフがこれに従うことができます。 – wcmatthysen

+1

私は[ここ](http://stackoverflow.com/questions/18215415/how-to-debug-a-user-defined-aggregate-function-in-oracle-11g)に質問したところ、ユーザー関数を作成するだけで、パッケージ内では機能しないときには、定義された集約関数が機能します。私の場合(〜3年後)、エラーは表示されませんが、誤った出力が返されます。したがって、私のように、この質問に遭遇する他の誰かに:ユーザー定義の集計関数がパッケージ内で動作していない場合は、関数を使用してみてください。 – Lawtonfogle