【问题标题】:how to create procedure/function from sql query using oracle?如何使用 oracle 从 sql 查询创建过程/函数?
【发布时间】:2020-09-28 18:01:17
【问题描述】:

我有一个有趣的情况

这是我的代码

SELECT :dateSend, t.senderPostindex, t.recipientPostindex, d.shipment_days FROM TABLE t
INNER JOIN shipment_days d on d.first_index = t.senderIndex and d.second_index = t.recipientPostindex
WHERE t.senderPostindex = variablesenderPostindex AND t.recipientPostindex = variablerecipientPostindex

基本上,我需要像 getShipmentDays('01001', '02031', '2020/05/09 15:40:00') 这样的程序 它必须归还我

  • 日期发送:2020/05/09 15:40:00
  • senderPostindex: 01001
  • recipientPostindex: 02031
  • shipment_days:5

我试图创建这个功能,但老实说我很难理解它,有人可以帮我吗?个人电脑。 dateSend 是一个绑定变量,我没有它

【问题讨论】:

    标签: oracle function stored-procedures stored-functions bindvalue


    【解决方案1】:

    一种选择是使用OUT 参数创建一个过程。

    由于你没有发布测试用例,我自己创建了一个。

    SQL> create table taby as
      2    select 1 senderindex, 1 recipientpostindex, 1 senderpostindex from dual;
    
    Table created.
    
    SQL> create table shipment_days as
      2    select 5 shipment_days, 1 first_Index, 1 second_index from dual;
    
    Table created.
    

    您的查询已转换为过程:

    SQL> create or replace procedure getshipmentdays
      2    (par_date    in out date,
      3     par_varsend in     varchar2,
      4     par_varrec  in     varchar2,
      5     --
      6     par_sendix  out    taby.senderpostindex%type,
      7     par_recix   out    taby.recipientpostindex%type,
      8     par_days    out    shipment_days.shipment_days%type
      9    )
     10  as
     11  begin
     12    select par_date,
     13           t.senderpostindex,
     14           t.recipientpostindex,
     15           d.shipment_days
     16      into par_date,
     17           par_sendix,
     18           par_recix,
     19           par_days
     20      from taby t join shipment_days d on d.first_index = t.senderindex
     21                                      and d.second_index = t.recipientpostindex
     22      where t.senderpostindex = par_varsend
     23        and t.recipientpostindex = par_varrec;
     24  end;
     25  /
    
    Procedure created.
    

    测试:由于有多个OUT 参数,您必须声明变量以接受它们的值。

    SQL> set serveroutput on;
    SQL> declare
      2    l_date    date := date '2020-06-09';
      3    l_sendix  taby.senderpostindex%type;
      4    l_recix   taby.recipientpostindex%type;
      5    l_days    shipment_days.shipment_days%type;
      6  begin
      7    getshipmentdays(l_date, 1, 1, l_sendix, l_recix, l_days);
      8    dbms_output.put_line('date = ' || l_date     ||', '||
      9                         'senderPostindex = '    || l_sendix ||', '||
     10                         'recipientpostindex = ' || l_recix  ||', '||
     11                         'shipment_days = '      || l_days
     12                        );
     13  end;
     14  /
    date = 09.06.20, senderPostindex = 1, recipientpostindex = 1, shipment_days = 5
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    另一种选择是创建一个返回 refcursor 的函数:

    SQL> create or replace function fgetshipmentdays
      2    (par_date    in  date,
      3     par_varsend in  varchar2,
      4     par_varrec  in  varchar2
      5    )
      6  return sys_refcursor
      7  as
      8    l_rc sys_refcursor;
      9  begin
     10    open l_rc for
     11    select par_date,
     12           t.senderpostindex,
     13           t.recipientpostindex,
     14           d.shipment_days
     15      from taby t join shipment_days d on d.first_index = t.senderindex
     16                                      and d.second_index = t.recipientpostindex
     17      where t.senderpostindex = par_varsend
     18        and t.recipientpostindex = par_varrec;
     19    return l_rc;
     20  end;
     21  /
    
    Function created.
    
    SQL> var rc refcursor
    SQL> exec :rc := fgetshipmentdays(date '2020-06-09', 1, 1);
    
    PL/SQL procedure successfully completed.
    
    SQL> print rc
    
    :B3      SENDERPOSTINDEX RECIPIENTPOSTINDEX SHIPMENT_DAYS
    -------- --------------- ------------------ -------------
    09.06.20               1                  1             5
    
    SQL>
    

    或者,如您所愿,使用表格函数。

    先创建类型:

    SQL> create type t_sd_row as object
      2    (datum  date,
      3     sendix varchar2(10),
      4     recix  varchar2(10),
      5     days   number
      6    );
      7  /
    
    Type created.
    
    SQL> create type t_sd_tab as table of t_sd_row;
      2  /
    
    Type created.
    

    功能:

    SQL> create or replace function getshipmentdays
      2    (par_date    in  date,
      3     par_varsend in  varchar2,
      4     par_varrec  in  varchar2
      5    )
      6  return t_sd_tab as
      7    l_tab t_sd_tab := t_sd_tab();
      8  begin
      9    select t_sd_row(par_date,
     10                    t.senderpostindex,
     11                    t.recipientpostindex,
     12                    d.shipment_days
     13                   )
     14      bulk collect into l_tab
     15      from taby t join shipment_days d on d.first_index = t.senderindex
     16                                      and d.second_index = t.recipientpostindex
     17      where t.senderpostindex = par_varsend
     18        and t.recipientpostindex = par_varrec;
     19    return l_tab;
     20  end;
     21  /
    
    Function created.
    

    测试:

    SQL> select * from table(getshipmentdays(date '2020-06-08', 1, 1));
    
    DATUM            SENDIX     RECIX            DAYS
    ---------------- ---------- ---------- ----------
    08/06/2020 00:00 1          1                   5
    
    SQL>
    

    【讨论】:

    • 你能举个例子,我如何使用 select 来执行这个函数吗?我需要使用 select... 类似于 "SELECT * FROM TABLE(getshipmentdays(CURRENT_TIMESTAMP, '01001','65012'));"
    • 当然;我编辑了答案并添加了另一个示例。
    • 还有一个问题,如何将它与 TIMESTAMP 一起使用?我收到一个错误.. 我的意思是 TIMESTAMP 而不是 DATE
    • 好吧,使用时间戳并传递时间戳而不是日期,例如select * from table(getshipmentdays(timestamp '2020-06-08 21:16:20.123', 1, 1));
    • 4 ORA-22905: 无法访问非嵌套表项 SQL3.sql 1 15 ...中的行
    猜你喜欢
    • 2022-01-13
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多