简体   繁体   English

DB2 - 使用字段作为时间计算的标记持续时间

[英]DB2 - use field as a labeled duration for time calculation

Given a table that looks like this:给定一个看起来像这样的表:

id  task                     scheduled_date    reminder
--  -----------------------  ----------------  --------
 1  mail january newsletter  2022-01-01        15 days

I had planned on executing a query to mimic date addition as in我曾计划执行一个查询来模拟日期添加

SELECT TASK, SCHEDULED_DATE + 15 DAYS FROM ...

==> 2022-01-16

Unfortunately, using the REMINDER field gives an error:不幸的是,使用REMINDER字段会报错:

SELECT TASK, (SCHEDULED_DATE + REMINDER) FROM ...

==>[Code: -182, SQL State: 42816]  [SQL0182] A date, time, or timestamp expression not valid.

Is there any way to accomplish using the reminder field as a labeled duration?有什么方法可以将提醒字段用作标记的持续时间吗? (I'm using IBMi DB2) (我正在使用 IBMi DB2)

You'll need to convert the string "15 days" into an actual duration.您需要将字符串"15 days"转换为实际持续时间。

A date durration is a decimal(8,0) number representing YYYYMMDD日期持续时间是表示 YYYYMMDD 的decimal(8,0)数字

So 15 days would be 00000015所以 15 天将是00000015
1 year, 00010000 1 年, 00010000
1 year 1 month, one day '00010101` 1年1月1日'00010101`

create table testdur (
  datedur decimal(8,0)
);

insert into testdur
  values (15), (10000), (10101), (90), (300);

select current_date as curDate
  , dateDur
  ,current_date + dateDur
from testdur;

Results结果
在此处输入图像描述

You may create a user defined finction for this.您可以为此创建一个用户定义的函数。
I don't have Db2 for IBM i at hand, but it should work as for Db2 for LUW.我手头没有用于 IBM i 的 Db2,但它应该像用于 LUW 的 Db2 一样工作。

create or replace function add_interval
(
  p_date date
, p_interval varchar (100)
)
returns date
begin atomic
  declare v_pattern varchar (35) default '([+-]? *[0-9]+) *(day|month|year)';
  declare v_y int default 0;
  declare v_m int default 0;
  declare v_d int default 0;
  declare v_occ int default 1;
  declare v_num int;
  declare v_kind varchar (5);
  declare v_interval varchar (100);

  set v_interval = lower (p_interval);
  l1: while true do
    set v_kind = regexp_substr 
      (
        v_interval
      , v_pattern
      , 1, v_occ, '', 2
      );
    if v_kind is null then leave l1; end if;
    set v_num =
    int 
    (
      regexp_substr
      (
        v_interval
      , v_pattern
      , 1, v_occ, '', 1
      )
    );
    if v_kind = 'day' 
      then set v_d = v_d + v_num;
    elseif v_kind = 'month'
      then set v_m = v_m + v_num;
    elseif v_kind = 'year'
      then set v_y = v_y + v_num;
    end if;
    set v_occ = v_occ + 1;
  end while l1;
  return p_date 
    + v_y year
    + v_m month
    + v_d day
  ;
end
select 
  i
, add_interval (date ('2023-02-07'), i) d
from
(
  values
    ('15 days')
  , ('15day')
  , ('15days - 1 days + 1 month - 2 year')
) t (i)
I D
15 days 15天 2023-02-22 2023-02-22
15day 15天 2023-02-22 2023-02-22
15days - 1 days + 1 month - 2 year 15天-1天+1个月-2年 2021-03-21 2021-03-21

fiddle小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM