5

我已经构建了这个函数,它必须根据该质押 ID 向我返回质押的第一个付款到期日。我的表中的每个承诺都有一个日期,付款发生在每个月的第一天,从承诺日期的下个月开始。我需要从匿名块中调用它......希望它足够清楚......

这是功能代码

create or replace function DD_PAYDATE1_SF (

pledge_id dd_payment.idpledge%type)

return  date is 

payment_date  dd_payment.paydate%type;

begin 

select    paydate  into payment_date from dd_payment 
where dd_payment.idpledge = pledge_id;



return payment_date;

end  DD_PAYDATE1_SF;

我尝试了 trunc 函数,但它似乎将所有后续付款都退还给我——因为我在调用函数“精确提取返回的行数超过请求的行数”时收到此错误——而我只需要其中的第一个我该如何解决它

4

2 回答 2

3

您需要加入具有承诺日期的表(我猜pledge),过滤以仅获取之后的付款日期,并使用MIN聚合函数获取第一个日期:

create or replace function dd_paydate1_sf (
  pledge_id dd_payment.idpledge%type)
return  date is 
  payment_date dd_payment.paydate%type;
begin 
  select min(d.paydate)
  into payment_date
  from pledge p
  join dd_payment d on d.idpledge = p.pledge_id
  and d.paydate > p.pledge_date
  where p.pledge_id = dd_paydate1_sf.pledge_id;

  return payment_date;
end dd_paydate1_sf;
/

SQL 小提琴

尽管 join 和 filter 是否必要存在疑问,因为它们暗示您可以在承诺之前先付款,这实际上没有意义;因此,您可能只需添加MIN()到原始查询即可获得相同的效果。

这不会显示新承诺的第一个日期(本月收到的),并将返回 null。如果你也想要这些,并且你关于接下来几个月的第一个月的规则总是正确的,你可以忽略支付表并计算出它应该是什么:

create or replace function dd_paydate1_sf (
  pledge_id dd_payment.idpledge%type)
return  date is 
  payment_date dd_payment.paydate%type;
begin 
  select trunc(p.pledge_date, 'MM') + interval '1' month
  into payment_date
  from pledge p
  where p.pledge_id = dd_paydate1_sf.pledge_id;

  return payment_date;
end dd_paydate1_sf;
/

为您提供该TRUNC(<date>, 'MM')日期所在月份的第一天,然后您可以添加一个以获得下个月的第一天。

SQL 小提琴

这取决于您是想要第一个预期付款日期,还是实际进行第一次付款的日期,假设dd_payment正在记录已发生的实际付款。


在匿名块中获取和显示一个值:

declare
    paydate date;
begin
    paydate := dd_paydate1_sf(104);
    dbms_output.put_line(to_char(paydate, 'DD/MM/YYYY'));
end;
/
于 2013-05-31T15:50:40.710 回答
0

您必须更改您的选择语句。如果您想要第一个,您可以执行以下操作:

select   paydate  
into     payment_date
from 
       (select paydate 
        from   dd_payment 
        where  dd_payment.idpledge = pledge_id
        order  by paydate)
where    rownum = 1;
于 2013-05-31T15:47:14.787 回答