如何在 DB2 AS/400 中将十进制字段转换为日期字段?
Posted
技术标签:
【中文标题】如何在 DB2 AS/400 中将十进制字段转换为日期字段?【英文标题】:How do I cast a decimal field to a date field in DB2 AS/400? 【发布时间】:2010-06-14 16:06:27 【问题描述】:我有一个 DECIMAL 字段,其中包含 AS400 格式的日期:1100614
我试过了:
cast (MYDATE as DATE)
但我不能将 DECIMAL 转换为 DATE,而
DATE(MYDATE)
返回空值。
如何将此字段转换为 DATE 字段?
【问题讨论】:
那是 CYYMMDD 吗?其中 1 = 20?那么这将是 20100614 吗? 问题是“CYYMMDD”不完全是“AS/400 格式”。它是许多过去(和现在)开发人员使用的格式,因为他们不知道如何处理真正的 DATE 值,并且因为它起源于真正的数据库 DATE 定义甚至存在之前。 Inertia 在过去几十年里一直保持这种形式。系统上的现代 DATE 值看起来并不像那样,而且已经很长时间没有了。不幸的是它仍然在这么多表中。 【参考方案1】:假设它是 CYYMMDD,就像我在上面的评论中问的那样,这里有几个选项:
-
Convert CYYMMDD format to datetime - SQL
convert cyymmdd (AS400) format to datetime format
可以做到,但并不容易。如果您需要经常执行此操作,可能值得您花时间编写自己的函数来执行此操作。
【讨论】:
我希望我可以使用内置函数以日期格式投射。 @kevin 我查看了 IBM 的手册,没有看到对 CYYMMDD 的任何支持。【参考方案2】:如果您使用的是 IBM i 6.1 或更高版本,这将起作用,但我预感您使用的是旧版本的操作系统。我从this forum post 偷了加法技巧。
create table dec1 (f1 decimal(7,0))
insert into dec1 values 1100614
select date(timestamp_format(char(f1+19000000), 'YYYYMMDD')) from dec1
结果:
DATE
06/14/10
******** End of data ********
Here's the reference 转换为 DB2 for i SQL 中支持的日期字符串格式。
【讨论】:
【参考方案3】:一个更简单(如果你想要自己的函数更合适)的方法是
SELECT CAST(CAST(*DecimalDateFromDB2_Here* + 19000000 AS VARCHAR) AS DATETIME)
示例:
-显示 2000 + 日期
SELECT CAST(CAST(1040526 + 19000000 AS VARCHAR) AS DATETIME)
-显示 1999 + 日期
SELECT CAST(CAST(990526 + 19000000 AS VARCHAR) AS DATETIME)
【讨论】:
【参考方案4】:在我最近参加的 DB2 for IBM i 课程中,IBM 人员建议使用预先填充的转换表,其中包含您需要支持的所有不同格式的日期值。您每年只需要 365 或 366 行。然后,您加入此表进行转换。当然,您需要为每种格式创建索引才能获得良好的性能。一个人说执行连接甚至可能比调用转换函数更快。
另一个好处是可以在转换表中添加其他列如会计期、季度、营业日指标等,可以简化一堆查询,比如查找第三季度的所有订单。
例如,假设 DATECONV 表将 DATEFMT 列作为实际日期,将 CYMDFMT 列作为十进制日期,您的选择将是 选择日期,... FROM MYTABLE JOIN DATECONV on CYMDFMT=MYDATE
此解决方案的一个问题是,如果您将无效日期用作特殊值,例如 9999999,因为您不能在实际日期字段中包含无效日期。但是无论如何您都无法转换它们。
【讨论】:
【参考方案5】:一个 [而不是 简单] 表达式被验证可以追溯到 v5r3,并且可以将 MYDATE 列定义为 CHAR(7)、DEC(7)、NUMERIC( 7),INTEGER 或 FLOAT 数据类型 [或这些类型的更大长度/精度变体] 如下;此示例中显示的 DATE 转换标量正在转换字符串表达式 [per CONCAT] 的结果,该表达式生成一个 14 个字符的字符串,该字符串将作为格式为 'YYYYMMDDHHMMSS'
的 TIMESTAMP 有效:
DATE( DEC( 19000000 + MYDATE, 8, 0 ) CONCAT '000000' )
注意:上面的表达式可以[在别处看到]用数字转换标量编写,用于 DECIMAL 转换结果,但考虑到添加一个具有完整 8 位精度的值,这将是多余的,并且 DEC() 表达式从数字隐式转换为字符;处理 1000 年之前的日期时需要 DIGITS 以确保字符串结果中的前导零,或者在某些更旧的版本中,这些版本没有从数字到字符的隐式转换功能。 p>
IBM i 7.2->Database->Reference->SQL reference->Language elements->Data types->Datetime values->String representations of datetime values->Timestamp strings
【讨论】:
以上是关于如何在 DB2 AS/400 中将十进制字段转换为日期字段?的主要内容,如果未能解决你的问题,请参考以下文章