Подтвердить что ты не робот

Создайте функцию Oracle, которая возвращает таблицу

Я пытаюсь создать функцию в пакете, которая возвращает таблицу. Я надеюсь вызвать функцию один раз в пакете, но иметь возможность повторно использовать свои временные интервалы данных. Хотя я знаю, что создаю временные таблицы в Oracle, я надеялся сохранить вещи DRY.

До сих пор это то, что у меня есть:

Заголовок:

CREATE OR REPLACE PACKAGE TEST AS 

    TYPE MEASURE_RECORD IS RECORD (
      L4_ID VARCHAR2(50),
      L6_ID VARCHAR2(50),
      L8_ID VARCHAR2(50),
      YEAR NUMBER,
      PERIOD NUMBER,
      VALUE NUMBER
    );

    TYPE MEASURE_TABLE IS TABLE OF MEASURE_RECORD;

    FUNCTION GET_UPS(
      TIMESPAN_IN IN VARCHAR2 DEFAULT 'MONTLHY',
      STARTING_DATE_IN DATE,
      ENDING_DATE_IN DATE  
    ) RETURN MEASURE_TABLE;

END TEST;

Тело

CREATE OR REPLACE PACKAGE BODY TEST AS 

  FUNCTION GET_UPS (
    TIMESPAN_IN IN VARCHAR2 DEFAULT 'MONTLHY',
    STARTING_DATE_IN DATE,
    ENDING_DATE_IN DATE
  ) RETURN MEASURE_TABLE IS

    T MEASURE_TABLE;

  BEGIN

        SELECT  ...
        INTO    T
        FROM    ...

      ;

  RETURN T;

  END GET_UPS;

END TEST;

Компиляция заголовка, тело - нет. Одно сообщение об ошибке - "Недостаточно значений", что, вероятно, означает, что я должен выбирать в MEASURE_RECORD, а не MEASURE_TABLE.

Что мне не хватает?

4b9b3361

Ответ 1

Я думаю, вы хотите конвейерную функцию таблицы.

Что-то вроде этого:

CREATE OR REPLACE PACKAGE test AS

    TYPE measure_record IS RECORD(
       l4_id VARCHAR2(50), 
       l6_id VARCHAR2(50), 
       l8_id VARCHAR2(50), 
       year NUMBER, 
       period NUMBER,
       VALUE NUMBER);

    TYPE measure_table IS TABLE OF measure_record;

    FUNCTION get_ups(foo NUMBER)
        RETURN measure_table
        PIPELINED;
END;

CREATE OR REPLACE PACKAGE BODY test AS

    FUNCTION get_ups(foo number)
        RETURN measure_table
        PIPELINED IS

        rec            measure_record;

    BEGIN
        SELECT 'foo', 'bar', 'baz', 2010, 5, 13
          INTO rec
          FROM DUAL;

        -- you would usually have a cursor and a loop here   
        PIPE ROW (rec);

        RETURN;
    END get_ups;
END;

Для простоты я удалил ваши параметры и не реализовал цикл в функции, но вы можете видеть принцип.

Использование:

SELECT *
  FROM table(test.get_ups(0));



L4_ID L6_ID L8_ID       YEAR     PERIOD      VALUE
----- ----- ----- ---------- ---------- ----------
foo   bar   baz         2010          5         13
1 row selected.

Ответ 2

Чтобы вернуть всю таблицу сразу, вы можете изменить SELECT на:

SELECT  ...
BULK COLLECT INTO T
FROM    ...

Это полезно только для результатов, которые не являются чрезмерно большими, поскольку все они должны накапливаться в памяти перед возвратом; в противном случае рассмотрим конвейерную функцию, предложенную Чарльзом, или вернув КУРСОР REF.

Ответ 3

  CREATE OR REPLACE PACKAGE BODY TEST AS 

   FUNCTION GET_UPS(
   TIMESPAN_IN IN VARCHAR2 DEFAULT 'MONTLHY',
   STARTING_DATE_IN DATE,
   ENDING_DATE_IN DATE
   )RETURN MEASURE_TABLE IS

    T MEASURE_TABLE;

 BEGIN

    **SELECT   MEASURE_RECORD(L4_ID , L6_ID ,L8_ID ,YEAR ,
             PERIOD,VALUE )  BULK COLLECT  INTO    T
    FROM    ...**

  ;

   RETURN T;

   END GET_UPS;

END TEST;