为什么在存储过程内部,游标返回的结果集中的当前日期会被修改?

编程语言 2026-07-09

我需要就关于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'
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章