如何使用 oracle 从 sql 查询创建过程/函数?
Posted
技术标签:
【中文标题】如何使用 oracle 从 sql 查询创建过程/函数?【英文标题】:how to create procedure/function from sql query using oracle? 【发布时间】: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 是一个绑定变量,我没有它
【问题讨论】:
【参考方案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 ...中的行以上是关于如何使用 oracle 从 sql 查询创建过程/函数?的主要内容,如果未能解决你的问题,请参考以下文章
使用命令将存储过程查询从 sql 文件导入 Oracle DB