比较DB2中的日期

r7s23pms  于 2022-11-07  发布在  DB2
关注(0)|答案(3)|浏览(240)

我有一个查询,其中我连接了日、月、年的各个列,以形成格式为MM/DD/YYYY的日期,然后使用新连接的列获取12/16/2021(Dec 16 2021)之后的记录。
我已经尝试了多次比较日期,但没有运气。下面是我的问题:

select x.* from
(
Select date(to_date(p.PLDRM || '/' || p.PLDRD || '/' || p.PLDRY, 'MM/DD/YYYY')) as Departure_Date,
       date(to_date(p.PLARM || '/' || p.PLARD || '/' || p.PLARY, 'MM/DD/YYYY')) as Arrival_Date,
       date(to_date(p.PLLCM || '/' || p.PLLCD || '/' || p.PLLCY, 'MM/DD/YYYY')) as Change_Date,
       p.*
from post_table p
) x
where x.change_date > date('12/16/2021')

这将导致错误-日期、时间或时间戳字符串中的值无效

omqzjyyz

omqzjyyz1#

我敢打赌,您的表中有一些无效数据...
例如,月份为0,或〉= 13。
另一个可能的错误是MM/DD为02/30或02/31,甚至是02/29(非闰年)。
最好的办法是定义一个用户定义函数(UDF)来为您构建日期,这样您就可以为无效日期返回NULL。
或者,您可以检查特定的无效日期,并针对您的用例返回有效值。例如,02/30 ==〉02/28或02/29(如果在闰年)。
我手边没有任何代码示例,但如果有时间,我会把一些东西放在一起,然后编辑这个答案。

UDF示例

CREATE OR REPLACE FUNCTION DateBuilder (
            mm INTEGER, dd INTEGER, yyyy INTEGER
    )
    RETURNS DATE
    LANGUAGE SQL
    NO EXTERNAL ACTION
    DETERMINISTIC
    RETURNS NULL ON NULL INPUT
    BEGIN
        DECLARE invalidDate CONDITION FOR '22007';
        DECLARE EXIT HANDLER for invalidDate return NULL;
        return to_date(char(yyyy) concat '-' concat char(mm) concat '-' concat char(dd), 'YYYY-MM-DD');
    END;
hiz5n14c

hiz5n14c2#

更新:
当查询PLLCM、PLLCD、PLLCY的不同值时,我发现其中一个值是“0”(可能是为了避免出现NULL)。
在调整查询以避免这三列中出现“0”后,查询成功返回结果。

mcdcgff0

mcdcgff03#

与@Charles的想法相同,但使用了一个过程,因为我当时不能在函数体中使用处理程序(还没有检查现在是否可以使用):

CREATE OR REPLACE PROCEDURE castalesce_date_check_(IN strval VARCHAR(100))
LANGUAGE SQL
DETERMINISTIC
NO EXTERNAL ACTION
READS SQL DATA
BEGIN
    DECLARE retval INT DEFAULT 1;
    DECLARE dateval DATE;
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET retval=-1;
    SET dateval=DATE(strval);
    RETURN retval;
END @

CREATE OR REPLACE FUNCTION castalesce_date(strval VARCHAR(100))
RETURNS DATE
DETERMINISTIC
NO EXTERNAL ACTION
READS SQL DATA
BEGIN ATOMIC
  DECLARE retval INT;
  -- The following is needed because declaration of SQLEXECPTION handlers
  -- isn't allowed in UDFs:
  CALL castalesce_date_check_(strval);
  GET DIAGNOSTICS retval = DB2_RETURN_STATUS;
  IF retval = 1 THEN RETURN DATE(strval);
  ELSE RETURN NULL;
  END IF;
END @

db2 connect to ...
db2 -td@ -f ...

db2 "with post_table (PLDRY, PLDRM, PLDRD) as ( 
       values (1999, 12, 28),(1999,0,31),(2001,2,29) 
     ) select p.PLDRY, p.PLDRM, p.PLDRD 
     from post_table p 
     where castalesce_date(p.PLDRY || '-' || p.PLDRM || '-' || p.PLDRD) IS NULL"

PLDRY       PLDRM       PLDRD      
----------- ----------- -----------
       1999           0          31
       2001           2          29

2 record(s) selected.

事实证明,这可以大大简化这些天:

CREATE OR REPLACE FUNCTION castalesce_date(strval VARCHAR(100))
     RETURNS DATE
BEGIN
        DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
        BEGIN
                RETURN NULL;
        END;
        RETURN date(strval);
END @

FWIW,我有几个类似的函数用于其他类型,如XML。当必须清理临时数据时,它真的很方便。

相关问题