如何从下个月开始退回到期日

时间:2013-05-31 14:49:51

标签: sql oracle oracle11g

我已经建立了这个功能,必须返回基于该承诺ID的第一个付款到期日。我的桌子上有每个承诺的日期,付款发生在每个月的第一天,从承诺日期后的一个月开始。我需要从匿名区块调用它...希望它足够清楚... < / p>

这是功能代码

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;

我尝试了截断功能,但它似乎将所有后续付款返回给我 - 因为我在调用函数时收到此错误“精确提取返回超过请求的行数” - 虽然我只需要他们中的第一个 我该怎么解决呢?

2 个答案:

答案 0 :(得分: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 Fiddle

虽然加入和过滤是否必要是值得怀疑的,因为他们暗示你可以在承诺之前付款,这实际上没有意义;因此,只需将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 Fiddle

这取决于您是否需要第一个预期付款日期或实际首次付款的日期,假设dd_payment正在记录已发生的实际付款。


获取并显示匿名块中的一个值:

declare
    paydate date;
begin
    paydate := dd_paydate1_sf(104);
    dbms_output.put_line(to_char(paydate, 'DD/MM/YYYY'));
end;
/

答案 1 :(得分:0)

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

select   paydate  
into     payment_date
from 
       (select paydate 
        from   dd_payment 
        where  dd_payment.idpledge = pledge_id
        order  by paydate)
where    rownum = 1;