循环游标 - substr(char) 到日期,减去 sysdate - PLSQL Oracle

Cursor for loop - substr(char) to date, subtracting sysdate - PLSQL Oracle

也许有人可以帮助我.. 我在这里有循环游标。我想打印出名字和年龄(小数,例如 55,6 岁)。我知道我的代码的 WHERE 部分不正确。 我正在尝试使用 substr() 函数从 varchar2(12) 字符串中获取前 6 个字符(年份和月份)。然后我想将它更改为日期并从 sysdate 中减去。也许我错了。感到困惑:(

CREATE TABLE client(
pers_nr VARCHAR2(12) PRIMARY KEY,
fname VARCHAR2(20);

INSERT INTO client VALUES('19490321-789','Anna');


declare 
cursor c_info_client is select fname, substr(pers_nr, 1, 6)
                        from client
           --wrong!--   where substr(pnr, 1, 6) : = to_date(YYYY-MM) - sysdate;
begin
for rec in c_info_client loop
dbms_output.put_line(initcap(rec.fname) ||', ' || rec.pers_pnr ||' years');
end loop;
end;

答案应该类似于(多行之一):

安娜,34,7岁

您似乎根本不需要 where 子句;您想将 pers_nr 的前六个字符转换为一个日期,并查看该日期与今天之间相隔了多少年。

您可以通过以下方式计算年龄:

trunc(months_between(sysdate, to_date(substr(pers_nr, 1, 6), 'YYYYMM'))/12, 1)
  • substr(pers_nr, 1, 6) 给你六个字符 => 19490321
  • to_date(substr(pers_nr, 1, 6), 'YYYYMM') 将其转换为日期 => 1949-03-21
  • months_between(sysdate, ...) 给你月数 => 839.4
  • months_between(sysdate, ...)/12给你年数=> 72.196
  • trunc(..., 1) 将其截断到小数点后一位 => 72.1

因此您的 PL/SQL 块将是:

declare 
  cursor c_info_client is
    select fname,
      trunc(months_between(sysdate, to_date(substr(pers_nr, 1, 6), 'YYYYMM'))/12, 1) as age
    from client;
begin
  for rec in c_info_client loop
    dbms_output.put_line(initcap(rec.fname) ||', ' || rec.age ||' years');
  end loop;
end;
/

给出:

Anna, 72.1 years

db<>fiddle 带有光标和显示步骤的简单查询。

您可以使用 trunc(sysdate) 从今天早上的午夜开始计时,但在这里不会有太大区别。

默认情况下,将使用会话 NLS_NUMERIC_CHARACTERS 设置中的小数点分隔符显示年龄。如果您希望所有用户始终看到相同的分隔符,您可以使用 to_char() 和合适的格式掩码。