为什么在存储过程内部,游标返回的结果集中的当前日期会被修改?
我需要就关于CURSOR在 DB2 for LUW中返回日期的问题寻求帮助。
Dt_Noformat字段返回的日期不正确,而Dt_Format字段返回的日期正确。
这个问题只在使用游标时出现。单独执行查询时没有任何问题。
有人遇到过这个问题吗?我认为这是日期的隐式转换在发生作用,但我想知道原因。
简化的代码如下:
CREATE OR REPLACE PROCEDURE TEST_DATE_FORMAT()
DYNAMIC RESULT SETS 1
LANGUAGE SQL
SPECIFIC TEST_DATE_FORMAT
BEGIN
DECLARE CUR CURSOR WITH RETURN FOR
SELECT
CURRENT_DATE AS DT_NOFORMAT
,VARCHAR_FORMAT(CURRENT_DATE, 'YYYY-MM-DD') AS DT_FORMAT
FROM
SYSIBM.SYSDUMMY1;
OPEN CUR;
END;
返回的格式如下:
| DT_NOFORMAT | DT_FORMAT |
|---|---|
| 2027-12-04 | 2026-04-24 |
如果有人能提供帮助,我将不胜感激。
解决方案
“当单独执行时,查询没有问题。” -> 问题出在客户端,而不是DB2。
我建议你查看在客户端上安装的默认日期格式设置。
也许,看看在哪里以及如何 convert the column (field) of the cursor to a date。
作为一个假设:
DB2的日期被表示为4 字节:
2字节表示年份,1字节表示月份,1字节表示日期。
按这个顺序(YYYY-MM-DD)
Internally to DB2, the date is represented as a 4 byte field, with each byte containing 2 packed decimal digits stored in the format yyyymmdd
请参阅文档
以及 (https://www.ibm.com/docs/en/file-manager-for-zos/13.1.0?topic=reference-db2-data-types)
DATE A date is a three-part value representing a year, month, and day in the range of 0001-01-01 to 9999-12-31.
我猜您得到的列值(很可能是整数,或者可能是日期)是YYYYMMDD格式。在你的客户端(你显示 '2027-12-04' 的地方)你把它看成YYYYDDMM的格式。
接下来,转换类似于
DATEFFROMPARTS(YYYY,DD,MM)
instead of
DATEFFROMPARTS(YYYY,MM,DD)
在你的客户端上,可能会接受这样的默认值。
此外
'2026-04-28' ->DATEFFROMPARTS(2026,28,04)->(2026,12+12+04,04)->'2028-04-04'
Or
'2026-04-29' ->(2026,12+12+5,4)-> '2028-05-04'
或者更简单的示例
'2026-04-11' ->DATEFFROMPARTS(2026,11,04)->(2026,11,04)->'2026-11-04'
'2026-04-12' ->DATEFFROMPARTS(2026,12,04)->(2026,12,04)->'2026-12-04'
'2026-04-13' ->DATEFFROMPARTS(2026,12,04)+(13-12=1 month)->(2027,01,04)->'2027-01-04'
这种转换在某些系统(如SQL Server)上会导致错误。
在某些系统中,它将按我在示例中所示的方式计算(VBA)
dateserial(2026,24,04) ->2027-12-04
例如,在这种情况下,这就很有用了 :)
dateserial(2024,02,29)->'2024-02-29'
dateserial(2025,02,29)->'2024-03-01'