如何从存储的字符串日期(PL/SQL)打印十进制数字



尝试解决一个分配,其中我有一个由汽车所有者组成的表。我应该写一个匿名PLSQL语句,我应该打印名字,姓氏和主人的年龄,就像如果他们的工作是'19801109',它应该转换为他们的年龄在一个数字,有一个小数,像'34,4岁'。怎么做呢?(你可以想象,这是一种全新的体验)。下面是我的代码,没有任何函数的转换/计算:

declare
cursor c_owners is select initcap(fname), initcap(lname), dob
                from car_owner;
v_dob car_owner.pnr%type;
v_fnamn car_owner.fname%type;
v_enamn car_owner.lname%type;
begin 
  if not c_owners%isopen then
  open c_owner;
  end if;
     loop
     fetch c_owner
     into v_fname, v_lname, v_dob;
     exit when c_owners%notfound;
     dbms_output.put_line(v_fname||', '||v_lname||', '||v_dob||'year.');
     end loop;
close c_owners;
end;
/

如果有人能帮忙就太好了。这个问题困扰我有一段时间了。我知道我可以用更好的方式来写更少的代码,但我想先学习基础知识:)结果如下所示:

约翰·约翰逊,34岁,4岁。

当我问一个朋友他做过这样的事时:

begin 
for rec in select fname, lname, round (months_between(sysdate,  to_Date('19'|| 
SUBSTR(dob,0), INSTR(dob, '-')-1)'YYMMDD')) as age 
from car_owner; 
loop dbms_output.put_line(initcat(rec.fname) || ', '|| initcap(rec.lname) ||' , '|| rec.age||' age'; 
end loop; 
end;
/

但是没有工作(烦人的右括号错误无论我怎么做),我没有完全理解它,但也许它可以帮助你看到它应该是什么样子?表中大约有十行,输出应该根据他们的工作打印每个人的年龄。

你只需要算一下生日。将其转换为日期,从当前日期减去它并除以365得到年。然后使用to_char()格式化为1十进制:

SQL> with tbl(fname, lname, DOB) as
  2  ( select 'John', 'Johnson', '19081109' from dual
  3  )
  4  select fname, lname, to_char((sysdate - to_date('19801109','yyyymmdd'))/365, '99.9') age from tbl;
FNAM LNAME   AGE
---- ------- -----
John Johnson  34.6
SQL>

对于你的例子:

select initcap(fname), initcap(lname), to_char((sysdate - to_date(dob,'yyyymmdd'))/365, '99.9') || ' years old' age
                from car_owner;

关于在c#中获得精确的年龄,这里有一个很好的答案:给定日期时间

,以年为单位的十进制精度年龄

翻译成PL/SQL:

declare
  v_dob varchar(8) := '19801109';
  v_dob_as_date date := to_date(v_dob,'yyyymmdd');
  v_current_date date := sysdate;
  v_years integer;
  v_last_birthday date;
  v_next_birthday date;
begin
    v_years := extract(year from v_current_date) - extract(year from v_dob_as_date);
    v_last_birthday := ADD_MONTHS(v_dob_as_date, 12 * v_years);
    if v_last_birthday > v_current_date then
      v_years := v_years -1;
      v_last_birthday := ADD_MONTHS(v_dob_as_date, 12 * v_years);
    end if;
    v_next_birthday := ADD_MONTHS(v_last_birthday, 12);
    dbms_output.put_line('Years old (whole number): ' || v_years);
    dbms_output.put_line('Last birthday: ' ||  v_last_birthday);
    dbms_output.put_line('Next birthday: ' ||  v_next_birthday);
    dbms_output.put_line('Days between last and next birthdays: ' ||  (v_next_birthday - v_last_birthday));
    dbms_output.put_line('Days since last birthday: ' ||  (v_current_date - v_last_birthday));
    dbms_output.put_line('Exact age: ' || round(v_years + ( (v_current_date - v_last_birthday) / (v_next_birthday - v_last_birthday)),1));
end;

结果(SYSDATE为21-MAY-15 10:45:11 AM)是34.5。使用更简单的过程可以得到相同的结果:

declare
  v_dob varchar(8) := '19801109';
  v_dob_as_date date := to_date(v_dob,'yyyymmdd');
begin
  dbms_output.put_line('Age: ' || round(months_between(sysdate,to_date('19801109','yyyymmdd'))/12,1));
end;

如果四舍五入到小数点后5位,结果会有所不同。第一种方法产生34.52999,第二种方法产生34.53346。

最新更新