function - pl/sql 在函数中返回区间计算
问题描述
我有一些表格可以跟踪公交线路、站点以及它们的时间表。我正在尝试创建一个函数,该函数返回同一线路上两个巴士站之间的旅行时间,但我无法让该函数按预期工作。
功能代码:
create or replace function total_time_func(sch_id in sched.shid%type, stop_start in stops.sname%type, stop_end in stops.sname%type)
return interval day to second is
t_time interval day to second;
start_time stop_sched.scheduled_arrival%type;
end_time stop_sched.scheduled_arrival%type;
begin
select scheduled_arrival
into start_time
from stop_sched, stops
where stop_sched.sid = stops.sid
and stop_sched.shid = sch_id
and stops.sname = stop_start;
select scheduled_arrival
into end_time
from stop_sched, stops
where stop_sched.sid = stops.sid
and stop_sched.shid = sch_id
and stops.sname = stop_end;
t_time := end_time - start_time;
return t_time;
end;
函数编译不返回错误;但是,一旦我运行程序来调用函数的返回值,我就会收到一个错误。
从函数调用返回值的程序:
declare
total_time interval day to second;
begin
total_time := total_time_func(1, '5th', '7th');
if total_time > 0
then dbms_output.put_line('The total time is: ' || total_time);
else dbms_output.put_line('Stops Not Found');
end if;
end;
这是我收到的错误:
Error report -
ORA-01403: no data found
ORA-06512: at line 16
ORA-06512: at line 5
01403. 00000 - "no data found"
*Cause: No data was found from the objects.
*Action: There was no data from the objects which may be due to end of fetch.
我不确定我做错了什么,我已经多次重写并从头开始,但没有成功。同样值得注意的是,我知道我可能不使用函数就可以完成此任务;但是,我是使用函数的新手,我希望练习编写它们而不是放弃。
这些是我的参考表:
create table lines
(lid int,
lname varchar(30),
num_station int,
status int,
primary key(lid));
create table stops
(sid int,
sname varchar(30),
address varchar(100),
status int,
primary key(sid));
create table stop_line
(lid int,
sid int,
seq int,
primary key(lid,sid),
foreign key(lid) references lines,
foreign key(sid) references stops);
create table sched
(shid int,
lid int,
direction int,
primary key (shid),
foreign key (lid) references lines);
create table stop_sched
(shid int,
sid int,
scheduled_arrival interval day to second,
primary key (shid, sid),
foreign key(shid) references sched,
foreign key(sid) references stops);
作为旁注,我最初还在函数体中包含以下语句;但是,我根本无法在不返回错误的情况下编译该函数:
select shid
into sch_id
from sched
where sch_id = shid;
select sname
into stop_start
from stops
where stop_start = sname;
select sname
into stop_end
from stops
where stop_end = sname;
添加这些语句时返回的错误:
LINE/COL ERROR
--------- -------------------------------------------------------------
9/5 PL/SQL: SQL Statement ignored
10/10 PLS-00403: expression 'SCH_ID' cannot be used as an INTO-target of a SELECT/FETCH
statement
11/5 PL/SQL: ORA-00904: : invalid identifier
14/5 PL/SQL: SQL Statement ignored
15/10 PLS-00403: expression 'STOP_START' cannot be used as an INTO-target of a
SELECT/FETCH statement
16/5 PL/SQL: ORA-00904: : invalid identifier
19/5 PL/SQL: SQL Statement ignored
20/10 PLS-00403: expression 'STOP_END' cannot be used as an INTO-target of a
SELECT/FETCH statement
21/5 PL/SQL: ORA-00904: : invalid identifier
Errors: check compiler log
非常感谢您提供的任何指导,因为我在使用函数时遇到了很多麻烦。谢谢!
编辑以包括示例表值。stop_sched 表的第一行和最后一行应该满足参数(sch_id = 1,stop_start = '5th',stop_end = '7th'),但函数返回没有找到数据。
insert into stops values(1,'5th', '42 5th Avenue, Buffalo, NY 14201,1);
insert into stops values(2,'10th', ‘889 10th Avenue, Buffalo, NY 14201',1);
insert into stops values(3,'Main', '10 Main Street, Buffalo, NY 14201',1);
insert into stops values(4,'7th', '900 7th Avenue, Buffalo, NY 14201',0);
insert into schedule values(1,1, 1);
insert into schedule values(2,1, 1);
insert into stop_sched values(1, 1, interval '7:30:00.00' hour to second);
insert into stop_sched values(1, 2, interval '7:40:00.00' hour to second);
insert into stop_sched values(1, 3, interval '7:50:00.00' hour to second);
insert into stop_sched values(1, 4, interval '8:10:00.00' hour to second);
解决方案
Error report -
ORA-01403: no data found
ORA-06512: at line 16
ORA-06512: at line 5
01403. 00000 - "no data found"
*Cause: No data was found from the objects.
*Action: There was no data from the objects which may be due to end of fetch.
此错误清楚地表明您在函数内的查询没有return
任何行,并且您的匿名阻止了执行。
代码按预期工作。请看下面的演示:
表准备:
CREATE TABLE stops (
sid INT,
sname VARCHAR(30),
address VARCHAR(100),
status INT
);
insert into stops values (1,'A','DFDFD',1);
insert into stops values (2,'B','FDKJH',3);
insert into stops values (3,'C','IOIOS',4);
insert into stops values (4,'D','LKJJA',5);
CREATE TABLE stop_sched (
sid INT,
scheduled_arrival INTERVAL DAY TO SECOND
);
insert into stop_sched values (1,'3 12:30:06.7');
insert into stop_sched values (2,'4 12:30:06.7');
功能:
CREATE OR REPLACE FUNCTION total_time_func
(
-- sch_id IN number, --sched.shid%TYPE,
stop_start IN varchar2,--stops.sname%TYPE,
stop_end IN varchar2
)
RETURN INTERVAL DAY TO SECOND IS
t_time INTERVAL DAY TO SECOND;
start_time stop_sched.scheduled_arrival%TYPE;
end_time stop_sched.scheduled_arrival%TYPE;
BEGIN
select scheduled_arrival
into start_time
from stop_sched
Inner join stops
ON stop_sched.sid = stops.sid
-- and stop_sched.shid = sch_id
and stops.sname = stop_start;
select scheduled_arrival
into end_time
from stop_sched
inner join stops
ON stop_sched.sid = stops.sid
--and stop_sched.shid = sch_id
and stops.sname = stop_end;
t_time := end_time - start_time;
RETURN t_time;
END;
执行:
select total_time_func('A','B') OUTPUT from dual;
输出:
SQL> /
OUTPUT
-------
+01 00:00:00.000000
SQL>
DECLARE
total_time INTERVAL DAY TO SECOND;
BEGIN
total_time := total_time_func('A', 'B');
IF
total_time > 0
THEN
dbms_output.put_line('The total time is: ' || total_time);
ELSE
dbms_output.put_line('Stops Not Found');
END IF;
END;
输出:
Stops Not Found
推荐阅读
- flutter - inheritFromWidgetOfExactType(InheritedProvider
) 或 inheritFromElement() 之前被调用过 - mongoose - findOneAndUpdate() $set 如何只覆盖查询中定义的几个项目
- excel - 循环列并插入具有相对引用但每次插入公式时都设为绝对/固定的公式
- firebase - 带有多个应用程序的 Firebase 项目通知
- html - 当我试图悬停列表时下拉菜单消失
- javascript - 如何使用 jest 在 catch 块中的 if 语句中测试函数?
- c# - .net core 3 wpf/winforms(非 MSIX)的安装程序?
- python - 检查一列是否包含来自其他列的值并填充第三列(真或假)
- php - PHP 从多个 HTML 复选框更新 SQL
- c++ - 将检测到的 2D 地图调整为参考 2D 地图