RPG IV 文件处理问题

RPG IV Files processing issue

我还在学习角色扮演游戏和AS/400。来自 MS C#.NET。 我们目前正在转向 iSeries 机器,我正在尝试使用 IBM RPG 和 CL 编程,因为公司更需要它。

iSeries 版本如果我没看错的话是 dspdtaara QSS1MRI: ==> "V7R1M000 2924"

DSPSFWRSC+ F11 : ==>

 5770999   *BASE    5050     *CODE   QSYS        V7R1M0 L00 
 5770SS1   *BASE    5050     *CODE   QSYS        V7R1M0 L00 
 5770SS1   *BASE    2924     *LNG    QSYS        V7R1M0 L00    
 ... 
 5770WDS   56       5101     *CODE   QDEVTOOLS   V7R1M0  
 5770WDS   60       5050     *CODE   QDEVTOOLS   V7R1M0  

这是我的问题。

我有一个在旧 AS400 机器上生成并复制到新 iSeries 的平面文件 文件是一个带分隔符的数据(使用“;”),我需要重新格式化并导出到 FTP 以供外部公司进一步处理。每条记录有 29 或 28 列。因此,我做的第一件事是使用 SQLRPGLE 程序为缺少的记录添加一个额外的分隔符。在平面文件本身

 C/EXEC SQL 
 C+ SELECT  
 C+   MAX((length(trim(F00001))- length(REPLACE(trim(F00001),';',''))))
 C+ , MIN((length(trim(F00001))- length(REPLACE(trim(F00001),';',''))))
 C+ INTO :MaxCount, :@DelimCount 
 C+ FROM QGPL.fIncomming  
 C/END-EXEC        

  **/*  using the delimiter could fix data by inserting a delimiter in the proper place */

 C/EXEC SQL  
 C+ UPDATE QGPL.fIncomming
 C+  SET F00001 = INSERT(F00001,225,0,';') 
 C+ WHERE ( :MaxCount
 C+         - (  length(trim(F00001))  
 C+            - length(REPLACE(trim(F00001),';','')) )
 C+       ) > 0 
 C/END-EXEC   

然后我在 iSeries

上创建了 2 tables (PF)

Table1,这是一个 SQL table,根据传入的文件格式,有 29 列,(所有列都被命名并设置为数据的长度,但所有列都是文本(A ) 类型 )

和第二个 table (Table2) 与 table (Table1) 具有完全相同的布局,但每一列都根据需要具有特定的数据类型。 即 id 是 INTEGER 和 dateof 是 DATE 等

不,数据不干净。因此,日期字段中可能包含空格,或者货币字段中可能包含文本。

我需要将数据移动到 table2 的最佳方法,以便在传输过程中对其进行清理和验证。
SQL 方法是最好的,但是声明太大了,我无法真正正确地验证它。

有人可以建议(如果可能的话举个例子)其他方法或更好的方法来编写 SQL
我基本上有这个但是有很多错误:如果我尝试在 STRSQL 中 运行 它并不是所有的代码都适合屏幕。

SELECT
 TRIM(ORDERID) as ORDERID
...,LINENUM) <> ''
      THEN TRIM(LINENUM) 
      ELSE 9999 END as LINENUM
, TRIM(CUSTNUM) as CUSTNUM
, TRIM(PONUM) as PONUM
, CASE WHEN TRIM(REPLACE(ORDDATE,0,'')) <> ''
       THEN CAST(INSERT(INSERT(ORDDATE,5,0,'/'),3,0,'/') as Date) 
...
from Table1

根据要求: 这是原始的平面文件数据 [首先是列标题 c1-c29,用于包含 29 个有效分隔数据列的记录,然后是带有 <strong>*Err-> 的列标题 c1-c28 </strong> 指出辅助记录缺少预期分隔符和 30 个空格的位置 因为每条记录都应共享 相同的 布局,第三个是嵌入的 ruler-line 以显示第 225 个位置,在该位置将使用先前的 SQL 代码添加分号 并且可以添加可选的 30 个空格以保持fixed-length布局.]:

---c1----c2---c3----c4---------c5-------c6-------c7-------c8----------c9-----------c10-------c11--------------c12--------------c13----c14-c15---c16---c17---c18------c19---------c20------c21-----c22-------------c23-----------------------c24------------------c25----c26----c27------c28-----c29---
---c1----c2---c3----c4---------c5-------c6-------c7-------c8----------c9-----------c10-------c11--------------c12--------------c13----c14-c15---c16---c17---c18------c19---------c20------c21-----c22-------------c23-----*ERR->---c24--c25----c26-------c27-----c28-- **missing one column!**
....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+...10....+...11....+...12....+...13....+...14....+...15....+...16....+...17....+...18....+...19....+...20....+...21....+...22....+...23....+...24....+...25....+...26....+...27....+...28....+...29....+
1596555;001;10010;TEST5     ;01062015; 1213.00; 1219.00;  17.000;NET 30 DAYS ;            ;543534241;TOYYO1/5                ;  14OZ  ;T; 5.00; .500;   1; 560.00;          ;   560.00;01292015;5379602;** 2ND DAY **           ;5XDFSDFFGFGHGHGH16            ;      ;   ;          ;        ; 
1596555;   ;10010;          ;        ;        ;        ;        ;            ;            ;         ;                        ;        ; ;     ; .   ;    ;       ;          ;         ;01292015;5379602;                        ; 16.60;FRT;          ;        ; 
1598556;001;10021;TEST      ;02112015; 1237.00; 1207.00;  17.000;NET 30 DAYS ;            ;567860502;45GGH/4019              ;  10OZ  ;R;12.50; .000;   1; 105.42;          ;   105.42;02122015;5380313;** 2ND DAY **           ;3HGFH5456GFHFG5G27            ;      ;   ;          ;        ;
1598556;   ;10021;          ;        ;        ;        ;        ;            ;            ;         ;                        ;        ; ;     ; .   ;    ;       ;          ;         ;02122015;5380313;                        ; 13.19;FRT;          ;        ; 
1598557;001;10067;020415    ;02042015; 1283.00; 1238.00;  18.000;NET 30 DAYS ;            ;657870142;FTKG061/11              ;  14OZ  ;R;     ; .330;   1; 358.00;          ;   358.00;02092015;5380071;** 2ND DAY **           ;3NHJYJ64646GHJGHJ8            ;      ;   ;          ;        ;
1598557;   ;10067;          ;        ;        ;        ;        ;            ;            ;         ;                        ;        ; ;     ; .   ;    ;       ;          ;         ;02092015;5380071;                        ; 15.09;FRT;          ;        ;

这是当前由 MS SQL 进程生成的预期结果 [前面是嵌入式 ruler-line]:

....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+...10....+...11....+...12....+...13....+...14....+...15....+...16....+...17....+...18....+...19....+...20....+...21....+
"1596555",1,"10010","TEST5",01/06/2015, 1213.00, 1219.00, 17.00,"NET 30 DAYS",,"543534241","TOYYO1/5","14OZ","T",5.00,0.50,1, 560.00,, 560.00,01/29/2015,"5379602","** 2ND DAY **","5XDFSDFFGFGHGHGH16",,,,,
"1596555",9999,"10010",,,,,,,,,,,,,,,,,,01/29/2015,"5379602",,,"16.60","FRT",,,
"1598556",1,"10021","TEST",02/11/2015, 1237.00, 1207.00, 17.00,"NET 30 DAYS",,"567860502","45GGH/4019","10OZ","R",12.50,0.00,1, 105.42,, 105.42,02/12/2015,"5380313","** 2ND DAY **","3HGFH5456GFHFG5G27",,,,,
"1598556",9999,"10021",,,,,,,,,,,,,,,,,,02/12/2015,"5380313",,,"13.19","FRT",,,
"1598557",1,"10067","020415",02/04/2015, 1283.00, 1238.00, 18.00,"NET 30 DAYS",,"657870142","FTKG061/11","14OZ","R",,0.33,1, 358.00,, 358.00,02/09/2015,"5380071","** 2ND DAY **","3NHJYJ64646GHJGHJ8",,,,,
"1598557",9999,"10067",,,,,,,,,,,,,,,,,,02/09/2015,"5380071",,,"15.09","FRT",,,

我会直接将 FIncomming 读取到 RPG 程序中,而不用担心缺少分隔符。我猜它无论如何都在记录的末尾(你并没有真正告诉我们)。像在 C/C++ 中那样解析文件,RPGIV 可以使用标准 C 库。对于每条记录,验证字段,如果所有字段都有效,则直接写入问题中提到的 Table 2。有错误的记录将被写入 Table 1 以进行修复。

现在您提到需要将数据 FTP 提供给外部公司,这完全是另一个问题。 Scott Klement 有一个 API,您可以直接从 RPG 中使用它来 FTP 文件。他的网站是 http://www.scottklement.com

另外一件事,鉴于您是 RPG 新手,您可能想要学习自由格式而不是固定格式变体,因为这是编写 RPG 的现代方式。自由格式的 SQL 语句如下所示:

  exec sql  
    UPDATE qgpl.fIncomming
      SET F00001 = INSERT(F00001,225,0,';')
      WHERE :MaxCount - length(trim(F00001) - length(REPLACE(trim(F00001),';',''))) > 0;

有很多方法可以从数据库文件生成逗号分隔文件。最简单的是使用 CL 命令 CPYTOIMPF,提示它,你就可以看到选项。该命令还可以将文件直接放入 IFS 并转换为 ASCII 以传输到 MS-SQL.


编辑 2017 年 3 月 3 日

哇,看起来有些人正在使用一些非常古老的东西。因此,如果您使用的是 i5/OS 或 V5R4 之前的 OS/400 版本,则代码如下所示

c/exec sql  
c+  UPDATE qgpl.fIncomming
c+    SET F00001 = INSERT(F00001,225,0,';')
c+    WHERE :MaxCount - length(trim(F00001) - length(REPLACE(trim(F00001),';',''))) > 0;
c/end-exec

这是固定格式,请注意 c 规范。如果您在此旧版本上以自由格式编码,并且需要 SQL 预编译器理解您在做什么,则需要在固定格式周围添加 /end-free/free 编译器指令你的部分代码。 @Dam 在评论中加入了 link。

我[尚未]获得"comment"的授权,所以我正在使用"answer"功能来获取更多信息:-(
关于 OP 中的声明“我在 iSeries 上创建了 2 个表 (PF)”,不包括这两个 TABLE 对象的 SQL DDL。拥有这些信息将更好地允许场景的审阅者使用已经定义的 TABLE 提出一些想法,而不是审阅者提出在场景的约束 mandated\established 内可能不可接受的其他东西;鉴于 SELECT 和 UPDATE 语句显然引用了那些 [尚未描述] 表,我们只能假设这两个表是必需的。
FWiW,在呈现 issue\scenario 时,最好提供所有相关细节 [无论如何尽可能多地合理],以获得有价值的反馈;否则,一个主题最终会收到许多 评论 要求对场景进行额外说明。这个话题似乎已经发生了。