Как я могу написать эту процедуру по-другому - PullRequest
1 голос
/ 20 января 2011

Я хочу написать следующую процедуру по-другому, чтобы я мог вызвать ее для возврата данных, как если бы это была таблица, выполнив: SELECT * FROM table(package.get7DayCapacityDemandProv(1, sysdate))

Procesdure:

 PROCEDURE get7DayCapacityDemandProv(p_H_id                  IN     work_entity_data.H_id%TYPE
                                     ,p_date                         IN     DATE
                                     ,p_capacity_day_1                  OUT NUMBER
                                     ,p_demand_day_1                    OUT NUMBER
                                     ,p_capacity_day_2                  OUT NUMBER
                                     ,p_demand_day_2                    OUT NUMBER
                                     ,p_capacity_day_3                  OUT NUMBER
                                     ,p_demand_day_3                    OUT NUMBER
                                     ,p_capacity_day_4                  OUT NUMBER
                                     ,p_demand_day_4                    OUT NUMBER
                                     ,p_capacity_day_5                  OUT NUMBER
                                     ,p_demand_day_5                    OUT NUMBER
                                     ,p_capacity_day_6                  OUT NUMBER
                                     ,p_demand_day_6                    OUT NUMBER
                                     ,p_capacity_day_7                  OUT NUMBER
                                     ,p_demand_day_7                    OUT NUMBER
                                     )
  IS
  BEGIN

    getCapacityDemandOnDayProvider(p_H_id
                                  ,p_date
                                  ,p_capacity_day_1
                                  ,p_demand_day_1
                                  );

    getCapacityDemandOnDayProvider(p_H_id
                                  ,p_date + 1
                                  ,p_capacity_day_2
                                  ,p_demand_day_2
                                  );

    getCapacityDemandOnDayProvider(p_H_id
                                  ,p_date + 2
                                  ,p_capacity_day_3
                                  ,p_demand_day_3
                                  );

    getCapacityDemandOnDayProvider(p_H_id
                                  ,p_date + 3
                                  ,p_capacity_day_4
                                  ,p_demand_day_4
                                  );

    getCapacityDemandOnDayProvider(p_H_id
                                  ,p_date + 4
                                  ,p_capacity_day_5
                                  ,p_demand_day_5
                                  );

    getCapacityDemandOnDayProvider(p_H_id
                                  ,p_date + 5
                                  ,p_capacity_day_6
                                  ,p_demand_day_6
                                  );

    getCapacityDemandOnDayProvider(p_H_id
                                  ,p_date + 6
                                  ,p_capacity_day_7
                                  ,p_demand_day_7
                                  );

  END get7DayCapacityDemandProv;

Ответы [ 4 ]

2 голосов
/ 20 января 2011

Вы хотите (1) преобразовать это в функцию, которая возвращает запись, а затем (2) преобразовать это в конвейерную функцию.

Вот пример. Я пропустил первый параметр, чтобы его можно было легко запустить, но вы можете просто добавить его обратно.

create or replace package test
as
  type theRecordType is record (
     day  date,
     capacity  number,
     demand  number
  );

  type theTableType is table of theRecordType;

  function getData(p_date DATE) return theTableType pipelined;
end test;
/

create or replace package body test
as
  function getData(p_date DATE) return theTableType pipelined
    as
      theRecord  theRecordType;
    begin
      for i in 0..6 loop
        theRecord.date := p_date + i;
        theRecord.capacity := i;
        theRecord.demand := i+1;
        --
        -- you would have a call to your procedure instead of the above two lines
        --      getCapacityDemandOnDayProvider(p_H_id
        --                          ,theRecord.date
        --                          ,theRecord.capacity
        --                          ,theRecord.demand
        --                          );
        --
        pipe row (theRecord);
      end loop;
      return;
    end getData;
end test;
/

Теперь вы можете выбирать из функции и получать по одной строке на каждый день.

select * from table(test.getData(SYSDATE));

Я сделал пакет, чтобы типы могли быть объявлены в заголовке пакета. В качестве альтернативы вы можете оставить ее автономной функцией и объявить типы в схеме, используя CREATE TYPE.

1 голос
/ 20 января 2011

Это не так, поэтому синтаксически он не будет на 100% корректным, но концептуально правильным будет.

create or replace package bingo IS
TYPE bingoCursor is REF CURSOR;

function get7Days(
    bingoId IN  bingoTable.bingoId%TYPE,
    bingoDate   IN  date)
    return bingoCursor;
end bingo;

create or replace package body bingo IS

function get7Days(
    bingoId IN  bingoTable.bingoId%TYPE,
    bingoDate   IN  date)
    return bingoCursor IS

    sevenDaysContent bingoCursor;
begin
    open sevenDaysContent for
        select day 1 stuff;

        union all

        select day 2 stuff;

        union all

        ... select and union all days 3 - day 7;

    return sevenDaysContent;
end get7Days;
end bingo;
0 голосов
/ 20 января 2011

Вы можете создать функцию, которая возвращает sys_refcursor.Слишком простой пример:

create or replace function BLAH(somevar in varchar2) return sys_refcursor IS
v_result_cur sys_refcursor;
v_query varchar2(4000);
...
begin
...
v_query := 'select field1, field2 from blah';
...
open v_result_cur for v_query;
return v_result_cur;
...
exception
...
end;

Но я скажу, что это не типично.Я бы, вероятно, использовал представление (или материализованное представление) или превратил бы эти внутренние процедуры в функции и просто выделил бы их, например:

select
FN_getCapacityDemandOnDayProvider(someVars) as Day1Val,
FN_getCapacityDemandOnDayProvider(someVars2) as Day2Val
from dual;
0 голосов
/ 20 января 2011

Звучит так, как будто вы хотите функцию или представление.Возвращенные данные процедуры могут быть перехвачены и использованы в скрипте SQL, но для этого требуется сначала вывести их в таблицу временных или переменных.

Если вы хотите иметь возможность просто выполнить SELECT * FROM something, тогда вам, вероятно, нужнофункция или представление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...