我给你写信是因为我不能在AS400数据库上使用操作符to_date
。
对于Oracle数据库,我使用:
datefield >= to_date('01/01/2014','DD/MM/YYYY')
但是对于AS400,我得到一个错误:
不兼容的操作符
是否有其他函数可以代替to_date
?
假设datefield是实际的日期数据类型
那么你所需要做的就是使用ISO格式的日期字符串
datefield >= '2014-01-01'
DB2 for IBM i将始终识别'2014-01-01'作为日期。
但是如果你真的想自己显式地转换它,那么有两个函数
DATE('2014-01-01')
CAST('2014-01-01' as DATE)
为了可移植性,首选CAST。
我建议使用ISO格式,尽管系统会识别美国的"mm/dd/yyyy"和欧洲的"dd.mm.yyyy"。
参考:http://www - 01. - ibm.com/support/knowledgecenter/ssw_ibm_i_71/db2/rbafzdtstrng.htm
我意识到这个话题是古老的,但目前的答案似乎大多忽略了TO_DATE的原始问题,而是提供了一个规避;当然,规避是IMO更好的方法。通过添加消息标识符和对原始问题和可能的解决方案的进一步解释,希望这些对其他人在将此讨论定位为与他们自己的问题相匹配时以及对提供的额外注释有益。
OP中描述的问题反映了错误条件SQL0401 [sqlcode -401]诊断TO_DATE标量的数据类型是TIMESTAMP,而DateField列的数据类型是DATE[或隐含的,尽管如果OP包含了TABLE的DDL,检查者可以确信"DateField"确实是DATE数据类型的列]。
在v5r3中,"Cause"由文本"日期、时间和时间戳操作数与字符操作数或同一类型的其他操作数兼容"描述;USEnglish[一级]文本很可能是"比较运算符>=操作数不兼容",而不仅仅是op中所指出的"不兼容的运算符"。即使是v7r1,文档也表明SQL0401:
http://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/rzala/rzalaml.htm
"……
日期、时间和时间戳操作数与字符、图形操作数或其他相同类型的操作数兼容。
…"
不考虑标量函数的名称,对于给定该名称的逻辑效果,标量结果是而不是 DATE数据类型;相反,该效果反映了标量函数名称TIMESTAMP_FORMAT,从而产生TIMESTAMP标量结果。绰号TO_DATE只是一个同义词语法替代:
http://www.ibm.com/support/knowledgecenter/api/content/ssw_ibm_i_71/db2/rbafzscatsformat.htm
在最初描述的场景datefield >= to_date('01/01/2014','DD/MM/YYYY')
中,对非标准日期格式进行编码,可以通过显式地将TO_DATE标量的结果转换为date类型来防止错误。例如,通过将TO_DATE结果包装在另一个[CAST]标量中,例如,DATE转换标量
datefield >= DATE(to_date('01/01/2014','DD/MM/YYYY'))
或CAST标量
datefield >= CAST(to_date('01/01/2014','DD/MM/YYYY') as DATE)
当然,使用格式化为标准日期格式之一的字符串的其他替代方法[例如Charles建议的*ISO]可能同样简单;即使这种用法没有像TO_DATE()的第二个参数指定的格式字符串那样显式地显示[给语句的审阅者]。但是根据最初显示为'DD/MM/YYYY'的规范,首选可能是使用*EUR标准格式,其格式为'DD.MM.YYYY';即编码为datefield >= '01.01.2014'
请注意,除了日期字符串文档参考http://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/db2/rbafzdatestrings.htm之外,还有另一种替代方案没有在该页上提到,这是*ISO格式字符串的一种冗余形式,DATE '2014-01-01'
和几乎相同的规格和冗余;另一种方法只是将括号]作为DATE [casting]标量规范DATE('2014-01-01')
进行输入,该规范在本主题的其他地方已经提到过。因此,每个datefield >= DATE'2014-01-01'
或datefield >= '2014-01-01'
或datefield >= DATE('2014-01-01')
都是等效的,并且每个都依赖于字符串的*ISO格式作为日期表示。