尝试解决一项任务,其中包含一个由汽车所有者组成的表格。我应该写一个匿名的PLSQL语句,我应该打印名字,姓氏和所有者的年龄,如果他们的dob是'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;
/
如果有人可以提供帮助,那会很棒。已经坚持了一段时间了。我知道我可以使用更好的写作方式来获得更少的代码但是首先要学习基础知识:)
结果应如下所示:
John,Johnson,34岁。
当我问他的朋友时他是这样做的:
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;
/
但那不起作用(无论我怎么做都令人烦恼的右括号错误),我完全不了解它,但也许它可以帮助你看看它应该是什么样子?表格中大约十行,输出应根据其dob打印每个年龄。
答案 0 :(得分:0)
你需要一些关于生日的数学。将其转换为日期,从当前日期减去它除以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;
答案 1 :(得分:0)
关于在C#中获得精确年龄,这是一个很好的答案: Age in years with decimal precision given a datetime
转换为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。