Пользовательская агрегатная функция внутри пакета
Я пытаюсь написать пользовательскую агрегатную функцию в 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 ответ
Oracle использует ORA-00600 для сигнализации необработанных исключений, например ошибок. Первый аргумент указывает на исключение; ORA-17090 - это общая "операция не разрешена". Часто они ограничены конкретными изменениями версии базы данных и платформы ОС. В других случаях это просто означает, что мы делаем что-то действительно необычное.
Включает ли пользовательская агрегатная функция в пакет "действительно необычный"? Точно сказать не могу. Конечно, нам разрешено включать функции картриджей данных в функции PL/SQL. Но определенные пользователем агрегаты являются частным случаем ODCI. Хотя документация не имеет явного правила для пакетов, все примеры реализуют агрегат с использованием CREATE FUNCTION
,
Так что делать? Ну, для сообщений ORA-00600 требуется вмешательство Oracle Support, так как для этого требуется патч. Если у вас есть учетная запись службы поддержки, вы можете узнать больше об этой конкретной проблеме здесь. Вам нужно будет поднять iTAR, чтобы получить дальнейшее разрешение. В противном случае я боюсь, что вам, вероятно, не повезло.