我正在尝试在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], [], [], [], [], [], [], [], [], [], [], []
是否可以在包声明中嵌套自定义聚合函数?
Oracle使用ORA-00600表示未处理的异常,即错误。第一个参数表示异常;第二个参数表示异常。ORA-17090是通用的“不允许操作”。通常,它们仅限于数据库版本和OS平台的特定排列。在其他时候,这只是意味着我们正在做一些非常不寻常的事情。
在包中包含自定义聚合函数是否算作“真的很不正常”?没有把握。当然,我们被允许在PL / SQL函数中包括数据盒带功能。但是用户定义的聚合是ODCI的特例。尽管文档没有针对软件包的明确规则,但所有示例都使用来实现汇总CREATE FUNCTION。
CREATE FUNCTION
那么该怎么办?好吧,ORA-00600消息需要Oracle支持,因为它需要一个补丁。如果您有支持帐户,则可以在此处找到有关此特定问题的更多信息。您将需要提高iTAR以获得进一步的解决方案。否则,恐怕您可能不走运。