【问题标题】:Cursor for loop - substr(char) to date, subtracting sysdate - PLSQL Oracle循环游标 - substr(char) 到日期,减去 sysdate - PLSQL Oracle
【发布时间】:2021-05-11 18:12:59
【问题描述】:

也许有人可以帮助我.. 我在这里有循环光标。我想打印出名字和年龄(以小数表示,例如 55,6 岁)。我知道我的代码的 WHERE 部分不正确。 我正在尝试使用 varchar2(12) 字符串中的 substr() 函数获取前 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 岁

【问题讨论】:

    标签: oracle plsql substr to-date sysdate


    【解决方案1】:

    您似乎根本不想要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() 和合适的格式掩码。

    【讨论】:

    • 您不知道我多么感谢您的回答(和解释)!非常感谢! :)
    猜你喜欢
    • 1970-01-01
    • 2020-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-09
    • 1970-01-01
    相关资源
    最近更新 更多