【问题标题】:How can I write this procedure differently如何以不同的方式编写此过程
【发布时间】:2011-01-20 12:40:23
【问题描述】:

我想以不同的方式编写以下过程,以便我可以调用它来返回数据,就像它是一个表一样:SELECT * FROM table(package.get7DayCapacityDemandProv(1, sysdate))

程序:

 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;

【问题讨论】:

  • 您的意思是希望 SELECT 返回一行 14 列,还是希望它返回 7 行,每天一行,每行 2 列?
  • @dave 编辑:理想情况下我想要 3 列和 7 行。列 = 天、容量、需求。 row= day1, day2, day3 等等,所以我可以把它放在图表中。如果不是,那么无论您能想到什么,我只想将其从程序中取出并放入我可以从中选择的表中

标签: sql database oracle plsql


【解决方案1】:

您希望 (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 在架构中声明类型。

【讨论】:

  • 编辑:有问题。它给了我一个错误,必须声明 getCapacityDemandOnDayProvider
  • 该错误的一些可能原因是:过程名称拼写错误(对我来说看起来不错)或参数类型不正确(您是否使用正确的类型声明 p_H_id?)或您使用的架构正在构建的包无权访问该过程。
【解决方案2】:

这是即兴的,所以它不会在语法上 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;

【讨论】:

  • 我的程序的哪一部分在选择日 x 位进行?我对 plsql 不是很熟悉,你能不能让它在使用我的程序时语法上更正确一些。谢谢
  • getCapacityDemandOnDayProvider 必须包含一个选择语句。用第 1 天的适当输入值替换“选择第 1 天的东西”。
  • 该过程调用另一个过程,然后调用许多不同的函数并进行计算,所以我不能像那样将选择语句放在那里
【解决方案3】:

听起来你想要一个函数或一个视图。可以在 SQL 脚本中捕获和使用过程返回的数据,但需要先将其转储到临时表或变量表中。

如果您的要求是能够执行SELECT * FROM something,那么您可能需要一个函数或一个视图。

【讨论】:

  • 是的,我需要一个包装函数。你知道我如何为这个特定的程序实现它吗?
【解决方案4】:

您可以创建一个返回 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;

【讨论】:

    猜你喜欢
    • 2023-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 1970-01-01
    • 2014-08-18
    相关资源
    最近更新 更多