在pl/sql程序中创建和调用函数

在pl/sql程序中创建和调用函数,sql,function,plsql,Sql,Function,Plsql,我创建了一个函数来返回一个租赁ID,然后在一个匿名PL/SQL程序中使用该ID,该程序根据租赁工具的价格和租赁时间单位的数量来计算租赁的总成本。(例如,租用4小时5美元的工具=总共20美元的租金) 创建函数的代码为: create or replace function return_rentalID (rental_id rental.rid%type) return integer is returned_rentalID integer; begin sel

我创建了一个函数来返回一个租赁ID,然后在一个匿名PL/SQL程序中使用该ID,该程序根据租赁工具的价格和租赁时间单位的数量来计算租赁的总成本。(例如,租用4小时5美元的工具=总共20美元的租金)

创建函数的代码为:

create or replace function return_rentalID (rental_id rental.rid%type)
     return integer is
     returned_rentalID integer;

begin
     select rid
     into returned_rentalID
     from rental
     where rental_id = rental.rid;
     return returned_rentalID;
exception
     when NO_DATA_FOUND
         then dbms_output.put_line('Rental ID Not Found');
         return -1;
end;
调用该函数的代码是:

declare
     returned_rentalID integer;
     units rental.num_unit%type;
     unit_price tool_price.price%type;
     rental_id rental.rid%type;

begin
     returned_rentalID := return_count(1);

     if returned_rentalID > 0 then

         select num_unit
         into units
         from rental
         where rid = returned_rentalID;

         select tp.price
         into unit_price
         from tool_price tp, rental r
         where tp.tid = r.tid
         and tp.tuid = r.tuid
         and rid = returned_rentalID;

         dbms_output.put_line('The Total Cost of this rental is $' || unit_price * units);

     else dbms_output.put_line('Rental ID Not Found');
     end if;
end;
如果我使用租赁ID 1作为参数或任何不存在的租赁ID,程序将正常工作;但是,对于所有其他有效的租赁ID,我在通过租赁ID 1时仍然得到相同的总数

有人知道是什么原因造成的吗?我知道使用函数返回租赁ID(returned_rentalID)是多余的,没有必要;但是,这是一个练习,可以轻松地创建和调用函数,因此这是必要的

我真的非常感谢您提供的任何见解

下面是我正在使用的表的一些示例代码:

create table tool_price
(tid int, --- too id 
tuid int, --- time unit id
price number,
primary key(tid,tuid),
foreign key(tid) references tool,
foreign key(tuid) references time_unit
);

--- mower, $20 per 4 hours. $30 per day 
insert into tool_price values(1,1,5.00);
insert into tool_price values(1,2,30);
insert into tool_price values(1,3,120);

insert into tool_price values(2,1,7.00);
insert into tool_price values(2,2,40);
insert into tool_price values(2,3,160);

insert into tool_price values(3,1,6.00);
insert into tool_price values(3,2,32);
insert into tool_price values(3,3,125);

insert into tool_price values(4,1,7.00);
insert into tool_price values(4,2,40);
insert into tool_price values(4,3,160);

create table rental 
(
rid int, --- rental id 
cid int, --- customer id 
tid int, --- tool id
tuid int, --- time unit id
num_unit int, --- number of units, if unit = 1 hour, num_unit = 5 means 5 hours. 
start_time timestamp, -- rental start time 
end_time timestamp, --- suppose rental end_time 
return_time timestamp,--- actual return time 
credit_card varchar(20),
total number, --- total charge 
primary key (rid),
foreign key(cid) references cust,
foreign key(tid) references tool,
foreign key(tuid) references time_unit
);
-- John rented a mower for 4 hours, 
insert into rental values(1,1,1,1,4,timestamp '2019-08-01 
10:00:00.00',null,null,'123456789',null);

-- susan rented a small carpet cleaner for one day 
insert into rental values(2,2,3,2,1,timestamp '2019-08-11 
10:00:00.00',null,null,'123456789',null);

--susan also rented a small mower for 5 hours, before 8 am case  
insert into rental values(3,2,1,1,5,timestamp '2019-08-12 
21:00:00.00',null,null,'123456789',null);

--david also rented a small carpet cleaner for 4 hours, after 10 pm case
insert into rental values(4,3,3,1,4,timestamp '2019-08-13 
19:00:00.00',null,null,'12222828828',null);

首先,感谢您提供示例数据。我将您的第二个select语句更改为ANSI join,并收到不同的1、2和3值:

   SELECT tp.price
      INTO unit_price
      FROM tool_price  tp
           INNER JOIN rental r ON tp.tid = r.tid AND tp.tuid = r.tuid
     WHERE rid = returned_rentalid;

我无法完全复制您的结果,因为您的示例中没有包含返回计数函数。

编写一个单独的函数来检查id的存在可能是一种过分的做法,您可能希望简化您的块,并使用以下方法删除该函数

declare
     v_total number(10,2);   
begin
     select tp.price * r.num_unit into v_total  
     from rental r
     join tool_price tp on (tp.tid = r.tid and tp.tuid = r.tuid)
     where r.rid = p_rental_id;  -- rental_id for total is to be calculated

     dbms_output.put_line('The Total Cost of this rental is $' || v_total);
exception 
    when NO_DATA_FOUND then
        dbms_output.put_line('No data found');
    when others then    
        raise;
end 
关于数据,请检查表中的内容,如果需要,可以从任何客户机直接运行sql(通过删除into子句)


注意:我手边没有数据库可以运行和检查,可能有轻微的语法错误,但概念和结构是有效的。

谢谢。你能提供一些关于包含return\u count函数的细节吗?return\u count(1)可能是一个输入错误,它应该是return\u rentalID(1)哦,是的!是的,谢谢你提供这个选择。选择一种方式比另一种方式有什么好处吗?我假设更简单的代码更容易被其他人解释和检查错误?