尝试解决一个分配,其中我有一个由汽车所有者组成的表。我应该写一个匿名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。