Ibm midrange 当前\u时间戳不总是填充

Ibm midrange 当前\u时间戳不总是填充,ibm-midrange,db2-400,rpgle,Ibm Midrange,Db2 400,Rpgle,这是运行在7.3版上的DB2fori 我目前正在评估将DDS定义的物理和逻辑文件转换为DDL定义的表和视图需要做什么。作为我测试的一部分,我遇到了一个不寻常的发现。给定一个表,其列定义为TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,当从RPGLE程序写入新行时,该值有时会正确填充,但大多数情况下不会。SQL插入似乎始终工作良好 以下是消息来源: QDDLSRC/SOT CREATE OR REPLACE TABLE SOT (

这是运行在7.3版上的DB2fori

我目前正在评估将DDS定义的物理和逻辑文件转换为DDL定义的表和视图需要做什么。作为我测试的一部分,我遇到了一个不寻常的发现。给定一个表,其列定义为TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,当从RPGLE程序写入新行时,该值有时会正确填充,但大多数情况下不会。SQL插入似乎始终工作良好

以下是消息来源:

QDDLSRC/SOT

CREATE OR REPLACE TABLE SOT (                                               
  ID   BIGINT        GENERATED ALWAYS AS IDENTITY (START WITH 1),           
  DESC CHAR(20)      NOT NULL DEFAULT '',                                   
  CTS  TIMESTAMP     NOT NULL DEFAULT CURRENT_TIMESTAMP,                    
  UTS  TIMESTAMP     NOT NULL FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP,
  PRIMARY KEY(ID)                                                            
) RCDFMT SOTR;                                                              
而要编辑它:

RUNSQLSTM SRCFILE(MYLIB/QDDLSRC) SRCMBR(SOT) DFTRDBCOL(MYLIB)
下面是执行写入操作的普通旧RPGLE程序的源代码:

QRPGLESRC/SOT1普通旧RPGLE代码

  CTL-OPT Optimize(*full);
  CTL-OPT Option(*nodebugio : *noshowcpy : *nounref : *srcstmt);
  CTL-OPT Dftactgrp(*no) Actgrp('QILE');
  CTL-OPT Bnddir('QC2LE');
  CTL-OPT Alwnull(*USRCTL);
//-----------------------------
  DCL-F sot disk(*ext) usage(*input : *output : *update) keyed;
//-----------------------------
  DCL-PR sot1 EXTPGM;
  END-PR sot1;

  DCL-PI sot1;
  END-PI;
//-----------------------------
  *INLR = *ON;

  desc = 'RPGLE I 1';
  WRITE sotr;

  CHAIN (1) sot;
  IF %FOUND(sot);
    desc = 'RPGLE U 1';
    UPDATE sotr;
  ENDIF;

  desc = 'RPGLE I 2';
  WRITE sotr;
//-----------------------------
  CTL-OPT Optimize(*full);
  CTL-OPT Option(*nodebugio : *noshowcpy : *nounref : *srcstmt);
  CTL-OPT Dftactgrp(*no) Actgrp('QILE');
  CTL-OPT Alwnull(*USRCTL);
//-----------------------------
  DCL-PR sot2 EXTPGM;
  END-PR sot2;

  DCL-PI sot2;
  END-PI;
//-----------------------------
  EXEC SQL
    INSERT INTO sot (desc)
    VALUES('SQLRPGLE I 1');

  EXEC SQL
    INSERT INTO sot (desc)
    VALUES('SQLRPGLE I 2');

  EXEC SQL
    UPDATE sot
    SET desc = 'SQLRPGLE U 1'
    WHERE id=5;

  *INLR = *ON;
//-----------------------------
这是一个执行插入的SQLRPGLE程序的源代码-这似乎工作得很好

QRPGLESRC/SOT2 SQLRPGLE代码

  CTL-OPT Optimize(*full);
  CTL-OPT Option(*nodebugio : *noshowcpy : *nounref : *srcstmt);
  CTL-OPT Dftactgrp(*no) Actgrp('QILE');
  CTL-OPT Bnddir('QC2LE');
  CTL-OPT Alwnull(*USRCTL);
//-----------------------------
  DCL-F sot disk(*ext) usage(*input : *output : *update) keyed;
//-----------------------------
  DCL-PR sot1 EXTPGM;
  END-PR sot1;

  DCL-PI sot1;
  END-PI;
//-----------------------------
  *INLR = *ON;

  desc = 'RPGLE I 1';
  WRITE sotr;

  CHAIN (1) sot;
  IF %FOUND(sot);
    desc = 'RPGLE U 1';
    UPDATE sotr;
  ENDIF;

  desc = 'RPGLE I 2';
  WRITE sotr;
//-----------------------------
  CTL-OPT Optimize(*full);
  CTL-OPT Option(*nodebugio : *noshowcpy : *nounref : *srcstmt);
  CTL-OPT Dftactgrp(*no) Actgrp('QILE');
  CTL-OPT Alwnull(*USRCTL);
//-----------------------------
  DCL-PR sot2 EXTPGM;
  END-PR sot2;

  DCL-PI sot2;
  END-PI;
//-----------------------------
  EXEC SQL
    INSERT INTO sot (desc)
    VALUES('SQLRPGLE I 1');

  EXEC SQL
    INSERT INTO sot (desc)
    VALUES('SQLRPGLE I 2');

  EXEC SQL
    UPDATE sot
    SET desc = 'SQLRPGLE U 1'
    WHERE id=5;

  *INLR = *ON;
//-----------------------------
最后,这里是我如何测试的。首先,我通过STRSQL插入了两条记录:

然后执行SOT1普通的旧RPGLE程序:调用SOT1

然后执行SOT2 SQLRPGLE程序:调用SOT2

然后查看来自WRKQRY的结果:

Line   ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+...10..

                            ID   DESC                  CTS                         UTS                      

000001                       1   RPGLE U 1             2018-04-18-16.05.13.520198  2018-04-18-16.05.26.275153

000002                       2   SQL I 2               2018-04-18-16.05.19.670653  2018-04-18-16.05.19.670653

000003                       3   RPGLE I 1             0001-01-01-00.00.00.000000  2018-04-18-16.05.26.274977

000004                       4   RPGLE I 2             2018-04-18-16.05.13.520198  2018-04-18-16.05.26.275196

000005                       5   SQLRPGLE U 1          2018-04-18-16.05.29.244307  2018-04-18-16.05.29.253463

000006                       6   SQLRPGLE I 2          2018-04-18-16.05.29.248723  2018-04-18-16.05.29.248723

****** ********  End of report  ********
请注意,第3行CTS列中的时间戳值不正确。然而,第4行在CTS中具有预期的时间戳值


你知道为什么会出现这种不一致的情况吗?

这完全符合预期。从RPG写入就是从SOT表写入整个记录。这包括在RPG中默认为空的CTS字段。SQL表不需要生成时间戳,因为您从RPG传入的时间戳是时间“0001-01-01 00:00:00.0000”。换句话说,您的RPG正在将以下值写入SQL表:

DESC: RPGLE U 1
CTS: '0001-01-01 00:00:00.0000'
UTS: '0001-01-01 00:00:00.0000'
UTS在表每次更新时都会更新,因此随后会更新到当前时间,以便看起来正确。CTS仅在未传递任何内容时更新,但实际上,在这种情况下传递了0

另一方面,SQL插入只插入DESC字段,因此表必须根据SQL规则生成默认时间。这将生成您期望的时间戳。与RPG正在执行的操作等效的语句如下所示:

Exec SQL
  Insert Into SOL (DESC, CTS)
  Values ('SQL I 1', Timestamp('00010101000000'));

按设计工作

默认值在未传递时生效,但正如@Playerfirst提到的,RPG将始终传递一个值

执行以下操作之一 -使用%timestamp BIF从RPG加载值
-通过一个视图/LF从RPG写入,该视图/LF在SOT1写入的第一条记录中没有字段

,描述为RPGLE I 1,CTS时间戳字段从未由程序初始化,或者您可以说它被初始化为0001-01-01-00.00.00.000000。在其第二次写入RPGLE I 2中,时间戳与第一条记录完全相同,因为时间戳由链操作初始化为第一条记录,然后从未清除或更改


DDL中的默认当前时间戳仅适用于SQL插入。RPG行为至少与它的传统是一致的

这不是时间0或时间戳0…这是'0001-01-01 00:00:00.0000'又名午夜0001年1月1日又名*洛瓦尔的时间戳字段。谢谢查尔斯。我返回并将其更正为工作值。我是从头开始的,其他一些SQL数据库允许使用0。