将基于十进制列的时间戳转换为实际时间戳时,使用HH24MISS扩展`format-string`时出现问题

时间:2015-08-21 13:32:35

标签: sql db2

TL;博士

为什么我无法转换以下字符串时间戳

select timestamp_format('2015-08-21 000000', 'YYYY-MM-DD HH24MISS') as timestamp
  from sysibm.sysdummy1;
在i7.1.0 / OS机器上

特别是因为我可以转换

select timestamp_format('000000' , 'HH24MISS') as timestamp
  from sysibm.sysdummy1;

为:

timestamp
-------------------------
2015-08-01 00:00:00.000000

上下文

在i7.1.0 / OS计算机上,我有一个表,其中时间戳数据分成几个十进制列,如

declare global temporary table tstamp
(
  year dec(4,0),
  month dec(2,0),
  day dec(2,0),
  time dec(6,0)
);

使用

等数据
insert into session.tstamp
  values (2015,8,21,92601),
         (2015,8,21,132601);

我想做一些日期过滤。鉴于格式有些不灵活,我认为如果我将其转换为时间戳并使用它来查询表格可能会更好。所以我咨询了i/OS 7.1 Manual on timestamp_format

我开始构建日期部分,最后以

结束
select
  timestamp_format(YEAR || '-' || MONTH || '-' || DAY, 'YYYY-MM-DD') as timestamp
  from session.tstamp;

返回

TIMESTAMP
--------------------------
2015-08-21 00:00:00.000000  
2015-08-21 00:00:00.000000  

完美,让我们添加时间部分和显式lpad它包含六个字符:

select
  timestamp_format(YEAR || '-' || MONTH || '-' || DAY || ' ' || lpad(TIME, 6, '0'), 'YYYY-MM-DD HH24MISS') as timestamp
  from session.tstamp;

这会导致以下错误:

  

SQL状态:22007

     

供应商代码:-20448

     

消息:[SQ20448]使用为TIMESTAMP_FORMAT指定的格式字符串,表达式无效。原因。 。 。 。 。 :由于以下原因之一,无法使用参数2中指定的格式字符串解释TIMESTAMP_FORMAT函数的参数1: - 字符串表达式太短或太长。 - 字符串表达式不符合格式字符串中指定的模板。 - 格式字符串中相应格式元素的字符串表达式中指定了太多数字。 - 字符串表达式中的值对格式字符串中的相应格式元素无效。恢复。 。 。 :为函数指定有效的格式字符串。再次尝试请求。

根据关于format-string的{​​{3}},字段之间的分隔符是可选的:

  

[...]   两个格式元素可以选择用以下一个或多个分隔符分隔:   [...]

问题

那么为什么在使用'YYYY-MM-DD HH24MISS'作为format-string时我的值不被接受,因为我明确将时间长度限制为六个字符?

旁注

可以HH24MISS单独使用format-string作为select timestamp_format(lpad(TIME, 6, '0'), 'HH24MISS') as timestamp from session.tstamp; TIMESTAMP -------------------------- 2015-08-01 13:26:01.000000 2015-08-01 09:26:01.000000 ,所以我真的无法理解这一点。

$(document).ready(function(e) {
    $('#button').click(function() {
		$('#menu').slideToggle();
		$('#bgr').toggleClass('display');
	});
});

2 个答案:

答案 0 :(得分:0)

所描述的困难是由于TIMESTAMP_FORMAT [aka TO_DATE]标量的缺陷造成的。正如预期的那样,所显示的请求已经过测试,与DB2 for IBM i 7.3一起运行[并且作为对OP的评论建议,也在v7r2上]。我问了一个类似的问题,"为什么使用我之前的例子失败?"在SQL convert text mm/dd/yy to date and timestamp,但我还没有重新访问这些新版本的示例。而且,对于具有最新代码的该功能,IBM i 7.1上可能会有一些更新的代码;我没有那种级别的维护,因此我无法测试该版本的[最后一项]增强功能是否包含新版本中明显存在的代码修复。

请注意,TO_DATE功能不是真正的内置[而是系统提供的用户定义函数(UDF)],所以我个人推荐一个替代方案;即,编写和使用特定于任务的标量UDF,和/或选择更兼容且更简单的方法,以便在定义时从这些列生成TIMESTAMP。考虑以下表达式[假设所有日期都超过1000年,否则表达式必须更改为使用DIGITS(YEAR)而不是YEAR]:

timestamp( YEAR concat digits( MONTH ) concat digits( DAY )
           concat digits( TIME )
         ) 

其变体是使用算术来实现14–character timestamp-string form 'yyyymmddhhmmss'

的相同效果
timestamp( concat( YEAR * 10000  + MONTH * 100 + DAY
                 , digits ( TIME ) ) )              

可以创建以下标量函数以避免在[VIEW]查询或其他位置编码表达式。在编码时,只有RETURN语句中的表达式,应该允许 in-lining ;我没有指定任何其他可能与性能相关的子句,例如parallel或on-null-input:

create function y4m2d2t6TS                   
( year   dec(4, 0)                           
, month  dec(2, 0)                           
, day    dec(2, 0)                           
, time   dec(6, 0)                           
) returns timestamp                          
language sql deterministic                   
return                                       
   digits( YEAR ) concat digits( MONTH )     
   concat digits( DAY ) concat digits( TIME )

; -- this semicolon is a statement separator, not terminator of above CREATE
select 
  y4m2d2t6TS( year, month, day, time ) as timestamp
from session.tstamp
; -- likeness of report from above query:
TIMESTAMP                 
2015-08-21-09.26.01.000000
2015-08-21-13.26.01.000000
********  End of data  ***

答案 1 :(得分:-1)

您可以在DB2中使用它:

values(VARCHAR_FORMAT(current_date,'YYYY-MM-DD HH24:MI:SS'))

再见

相关问题