DB2 iSeries打包字段转YYYY-MM-DD及日期筛选报错求助
嘿,我来帮你搞定这个查询报错的问题!你遇到的核心问题是:打包(PACKED)类型的日期字段不能直接用CHAR()转字符串后再用TO_DATE()按YYYY-MM-DD解析,因为打包字段存储的日期通常是CYYMMDD或YYYYMMDD的数字格式(比如2018-01-01会存成1180101或20180101),直接转CHAR()得到的字符串格式和YYYY-MM-DD不匹配,导致TO_DATE()解析失败。
下面给你几个靠谱的解决方案,按推荐优先级排序:
方案1:直接用DATE()函数转换(推荐)
DB2 iSeries的DATE()函数原生支持识别CYYMMDD格式的打包数字(这是IBM i上日期字段最常见的打包存储格式,其中C是世纪码:1代表2000-2099,0代表1900-1999)。直接用这个函数转换,既高效又不会出错:
SELECT * FROM table1 WHERE val = 145 AND DATE(dateShp) >= DATE('2018-01-01')
如果你的打包字段是YYYYMMDD格式(比如存的是20180101),这个方法同样适用,DATE()函数会自动识别这种格式。
方案2:用DIGITS()补前导零后再转换
如果方案1不生效(比如你的打包字段存储格式比较特殊),可以用DIGITS()函数代替CHAR()——它会把打包字段转换成带前导零的完整字符串,避免位数不足的问题。比如假设你的dateShp是PACKED(7,0)类型(存储CYYMMDD),可以这样写:
SELECT * FROM table1 WHERE val = 145 AND TO_DATE(DIGITS(dateShp), 'CYYMMDD') >= DATE('2018-01-01')
如果是YYYYMMDD格式的打包字段,把格式符改成YYYYMMDD即可:
SELECT * FROM table1 WHERE val = 145 AND TO_DATE(DIGITS(dateShp), 'YYYYMMDD') >= DATE('2018-01-01')
为什么你的原语句会报错?
你原来用CHAR(dateShp)转换打包字段时,得到的字符串是不带前导零的数字字符串(比如打包的1180101转成CHAR()是"1180101"),而你用TO_DATE()指定的格式是YYYY-MM-DD(需要10位带横杠的字符串),格式完全不匹配,所以系统会提示“表达式无效”。
内容的提问来源于stack exchange,提问作者Geoff_S

