RPG IV文件处理问题

时间:2015-04-09 20:36:58

标签: sql ibm-midrange rpgle rpg

我还在学习RPG和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 file是一个分隔数据(使用&#34 ;;")我需要重新格式化并导出到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个表(PF)

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

和第二个表(Table2)具有与表(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个有效列分隔数据的记录,然后是列标题c1-c28,其中*Err->指出预期分隔符和30个空格的位置辅助记录缺少,因为每条记录应该共享相同的布局,第三条记录应该是嵌入的标尺行,以显示分号将添加到的第225个位置之前的SQL代码和可选的30个空格可以添加以保持固定长度的布局。]:

---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进程当前生成的期望结果[以嵌入的标尺行开头]:

....+....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",,,

2 个答案:

答案 0 :(得分:2)

我会直接将FIncomming读入RPG程序,而不用担心丢失分隔符。我猜它是在记录的最后(你没有真正告诉我们)。像在C / C ++中一样解析文件,标准C库可用于RPGIV。对于每个记录验证字段,如果所有字段都有效,请直接写入问题中提到的表2。有错误的记录将写入表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日

哇,好像有些人正在使用一些非常古老的东西。因此,如果您使用的是V5R4之前的i5 / OS或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在评论中包含了一个链接。

答案 1 :(得分:2)

我尚未授权[还]进行“评论”,所以我使用“回答”功能代替,以征求更多信息:-(
  关于OP中“我在iSeries上创建了2个表(PF)”中的语句,未包含这两个TABLE对象的SQL DDL。拥有该信息将更好地允许该场景的审阅者使用已经定义的TABLE提出一些想法,而不是审阅者提出在该场景规定的约束条件内可能不可接受的其他内容;我们只能假设这两个表是一个要求,因为SELECT和UPDATE语句显然引用了那些[尚未描述的]表。
FWiW在提出问题时,提供所有相关细节[无论如何合理可能]最好,以获得有价值的反馈;否则,主题最终会收到许多评论,要求进一步澄清该方案。这个话题似乎已经发生了。