Я работаю с базой данных ERP, которая хранит много данных в многолетних таблицах. (Каждый новый год создается новая таблица для хранения данных за этот год) У нас есть требование иметь возможность запрашивать и составлять отчеты по некоторым из этих таблиц. Я в настоящее время использую представления, но представления становятся все больше и больше из года в год и медленнее. Я создал конвейерную табличную функцию, которая выполняет некоторый динамический sql и запрашивает соответствующие таблицы на основе даты и времени, переданной в качестве параметров. Я могу вызвать конвейерную функцию из обычного SQL, и она отлично работает. Однако цель состоит в том, чтобы иметь возможность повторно использовать табличные функции во многих различных хранимых процедурах и объединяться с другими данными. Используемая нами система отчетности требует использования хранимых процедур, возвращающих ссылки на курсоры.
Я создал тестовую функцию и протестировал хранимую процедуру (упрощенные версии для краткости), чтобы попытаться вернуть табличную функцию в качестве курсора, но я получаю ошибку при выполнении процедуры (PLS-00382: выражение имеет неправильный тип ). Я даже не уверен, можно ли получить доступ к функции конвейера с помощью процедуры, но я делал подобные вещи в SQL Server, поэтому должен быть какой-то способ. Я искал привет и низко, но на самом деле не могу найти кого-то с точно такой же ситуацией. Пожалуйста, смотрите мой код.
Ниже приведены пользовательские типы, которые я создал в своей схеме:
CREATE OR REPLACE TYPE PUCCONNECT.wo_trans_type AS OBJECT
(GL_YEAR INT,
SUBSYSTEM VARCHAR2(2)
);
CREATE OR REPLACE TYPE PUCCONNECT.wo_trans_table_test AS TABLE OF PUCCONNECT.wo_trans_type;
Ниже приведены объявления функций и процедур. Таблицы, из которых я выбираю функцию GL101Txx, имеют много столбцов, поэтому я выбираю только первые 2, чтобы упростить задачу. Эти первые 2 столбца имеют то же определение, что и столбцы, определенные в моем пользовательском объекте «wo_trans_type»
CREATE OR REPLACE FUNCTION PUCCONNECT.WO_MULTIYEAR_TEST(fromdate date, todate date)
RETURN WO_TRANS_TABLE_TEST PIPELINED IS
TYPE ref0 IS REF CURSOR;
cur0 ref0;
v_year_start int;
v_year_end int;
out_rec wo_trans_type
:= wo_trans_type(NULL,NULL);
BEGIN
v_year_start := EXTRACT(year FROM fromdate);
v_year_end := EXTRACT(year FROM todate);
FOR yearNumber in v_year_start..v_year_end LOOP
OPEN cur0 FOR
'SELECT ' || yearNumber || ' "gl_year", GL.SUBSYSTEM
FROM fmsdata.GL101T' || SUBSTR(to_char(yearNumber), 3,2) || ' GL
WHERE (GL.transaction_date BETWEEN ''' || fromdate || ''' AND ''' || todate || ''')';
LOOP
FETCH cur0 INTO out_rec.gl_year, out_rec.subsystem;
EXIT WHEN cur0 %NOTFOUND;
PIPE ROW(out_rec);
END LOOP;
CLOSE cur0;
END LOOP;
RETURN;
END WO_MULTIYEAR_TEST;
А вот процедура, в которой я пытаюсь использовать функцию:
CREATE OR REPLACE PROCEDURE PUCCONNECT."SP_WO_TRANS_PA" (
--table_out out wo_trans_table,
wo_trans_cursor out sys_refcursor
)
AS
BEGIN
OPEN wo_trans_cursor FOR
SELECT gl_year, subsystem
FROM TABLE( PUCCONNECT.WO_MULTIYEAR_TEST('01-jan-2019', '05-may-2019'));
END;
Кто-нибудь знает, возможно ли это с помощью хранимой процедуры? Возможно ли это с помощью нетранслируемых табличных функций? Будем благодарны за любые предложения или советы относительно лучшего метода достижения этого и поддержания производительности.
Вот полная ошибка, возвращаемая TOAD, когда я пытаюсь выполнить процедуру:
[Error] ORA-06550: line 12, column 12:
PLS-00382: expression is of wrong type
ORA-06550: line 12, column 6:
PL/SQL: Statement ignored
(1: 0): >> DECLARE
-- Declarations
l_WO_TRANS_CURSOR SYS_REFCURSOR;
BEGIN
-- Call
PUCCONNECT.SP_WO_TRANS_PA (WO_TRANS_CURSOR => l_WO_TRANS_CURSOR);
-- Transaction Control
COMMIT;
-- Output values, do not modify
:1 := l_WO_TRANS_CURSOR;
END;
Error at line 1
ORA-06550: line 12, column 12:
PLS-00382: expression is of wrong type
ORA-06550: line 12, column 6:
PL/SQL: Statement ignored
Вот как я называю это в TOAD:
DECLARE
-- Declarations
l_WO_TRANS_CURSOR SYS_REFCURSOR;
BEGIN
-- Call
PUCCONNECT.SP_WO_TRANS_PA (WO_TRANS_CURSOR => l_WO_TRANS_CURSOR);
-- Transaction Control
COMMIT;
-- Output values, do not modify
:1 := l_WO_TRANS_CURSOR;
END;