【问题标题】:Dynamically Reading COBOL Redefines with C#使用 C# 动态读取 COBOL 重新定义
【发布时间】:2016-03-07 14:54:31
【问题描述】:

我正在制作一个 C# 程序,它将能够动态读取用 COBOL 编写的 IBM HOST Copybook 并从中生成一个 SQL 表。生成表后,我可以将文件上传到我的程序中,它将读取、从 IMB-37 转换并将文件插入到该 sql 表中。到目前为止,我几乎可以处理任何事情,尽管我遇到了 REDEFINES 的一些问题。

例如:

           10   SOME-FIELD        PIC 9(3)      COMP-3.     SCRRB205
4117       10   SOME-OTHER-FIELD REDEFINES                  3041-17
4117              SOME-FIELD      PIC X(2).                 3041-17

我知道在这种情况下重定义取代了它上面的字段,尽管我不明白编译器如何知道它是否应该对其使用重定义。我假设在这种情况下,这是因为第一个是数字,而第二个是字符,尽管在下面的示例中它们都使用字符。

 05  STREET-ADDRESS.
       10  ADDRESS-LINE-1               PIC X(20).
       10  ADDRESS-LINE-2               PIC X(20).
   05  PO-BOX REDEFINES STREET-ADDRESS  PIC X(40). 

我尝试忽略重新定义,因为它总是占用相同数量的空间,但在原始字段被打包而重新定义的字段不是我需要知道何时解包字段的情况下。

这方面的任何帮助都会很棒!

【问题讨论】:

  • 这是一个设计问题,而不是编码问题。我认为您会希望使用原始定义之一来存储这些并忽略重新定义。但是,您可能希望保存有关重新定义的信息,以便知道如何在代码中处理它。当然,我猜你正在从 COBOL 转换为 C#/SQL Server。
  • 是的,我正在将 COBOL 转换为 SQL。我正在考虑仅将信息存储在原始定义中,但问题是当我将 EBCDIC 文本(从大型机下载)转换为 ASCII 时,我需要知道它使用哪个重新定义,因为我需要知道是否必须解包文本与否。
  • 很久没有想到COBOL了,但是我认为如果你对数据库进行第一个定义,那么如果需要,重新定义将在应用程序中处理。例如,您可以将 Address-Line-1、Address-Line-2 存储为最低级别的详细信息,然后在必要时在 C# 代码中创建 PO-BOX,但您可能会以不同的方式进行操作。这意味着,您不需要一个名为 PO-BOX 的数据变量。
  • 与您的第一个示例类似,您会将 SOME-FIELD PIC 9(3) 存储为正确的数据库详细信息,然后如果绝对必要,您可以在 C# 代码中将 int 转换为字符串。

标签: c# cobol mainframe ebcdic


【解决方案1】:

也许我可以帮助你,因为 2 年前我已经完成了你现在正在做的事情。

我必须设计一个 MySQL 数据仓库,包括 ETL 系统,完全基于在 Linux 上运行的 RM COBOL ERP 应用程序的文件。 该应用程序有 600 多个文件,目前尚不清楚其中有多少最终会进入数据库。大多数重要文件都在 COMP 字段上进行了索引,以使其更难,其中一个明显的要求是文件及其索引键之间的所有关系都可以在数据库上重现。所以我可能需要每个文件的每个字段。

考虑到文件的数量,手动一个一个地处理所有文件是没有问题的。

我只看到了一个实用的解决方案:应用automatic programming。即编写一个可以生成程序的程序,仅来自一个来源:cobol 抄写本。

我对允许使用的技术有一些限制(由客户设置)。我最终得到了一个 VB.NET 应用程序,该应用程序将 COBOL 字帖作为输入,并且:

  1. 生成 COBOL 程序,通过读取原始索引文件并将记录写入顺序文本文件,将数据转换为可利用的东西。
  2. 使用将这些数据文件从 MS Access 导入 MySQL 所需的所有代码生成 VBA 模块(包括 CREATE TABLE 和索引)

在项目开始时,我遇到了与现在完全相同的问题,尤其是那些该死的 REDEFINES。我发现列出和编码所有抄写本可能性的任务,如果不是不可能的话,至少是危险的。 所以我研究了另一种方式,发现了这个:

CB2XML

COBOL copybook 到 XML 转换器SourceForge

这为我节省了数周的字帖解析和解释工作。 它可以解析 COBOL 字帖,将它们变成一个 XML 文件,完美地描述所有具有许多有用属性的 PICTURE,例如 lengthtype。它完全支持 COBOL'86 标准。

发票文件示例(Facture 法语)

000001 FD  FACTURE.                                                     
000006 01  REC-FACTURE.                                                 
000011     03  FS1                  PIC X.                              
000016     03  FS2.                                                     
000021         05  FS2A            PIC 9.                               
               05  RFS2B           PIC X(8).
000026         05  FS2B REDEFINES RFS2B  PIC 9(8).
000031     03  FS3.                                                     
000036         05  FS3A            PIC 9.                               
000041         05  FS3B            PIC X(10).                            
000046     03  FS4.                                                     
000051         05  FS4A            PIC 99.                              
000056         05  FS4B            PIC 99.                              
000061         05  FS4C            PIC 99.                              
000066     03  FS5                 PIC X(5).                              
000071     03  FS6                 PIC X(20).                           
000076     03  FS7                 PIC 9.                               
000081     03  FS8                 PIC S9(9)V99    COMP-3.              
000086     03  FS9                 PIC S9(9)V99    COMP-3.              
000091     03  FS10                PIC 9.                               
000096     03  FS11                PIC S9(9)V99    COMP-3.              
000101     03  FS12                PIC S9(9)V99    COMP-3.              
000106     03  FS13                PIC S9(9)V99    COMP-3.              
000111     03  FS14-15 OCCURS 10.                                       
000116         05  FS14            PIC 9.                               
000121         05  FS15            PIC S9(9)V99    COMP-3.              
000126         05  FS16            PIC S9(9)V99    COMP-3.              
000131     03  FS17 OCCURS 10       PIC S9(9)V99    COMP-3.              
000136     03 FS18                 PIC 9(6).                            
000141     03  FS19                PIC 9.                               
000241     03  FILLER              PIC X.    

变成这样:

<copybook filename="FD8.COP.CLEAN">
    <item display-length="428" level="01" name="REC-FACTURE" position="1" storage-length="428">
        <item display-length="1" level="03" name="FS1" picture="X" position="1" storage-length="1"/>
        <item display-length="9" level="03" name="FS2" position="2" storage-length="9">
            <item display-length="1" level="05" name="FS2A" numeric="true" picture="9" position="2" storage-length="1"/>
            <item display-length="8" level="05" name="RFS2B" picture="X(8)" position="3" redefined="true" storage-length="8"/>
            <item display-length="8" level="05" name="FS2B" numeric="true" picture="9(8)" position="3" redefines="RFS2B" storage-length="8"/>
        </item>
        <item display-length="11" level="03" name="FS3" position="11" storage-length="11">
            <item display-length="1" level="05" name="FS3A" numeric="true" picture="9" position="11" storage-length="1"/>
            <item display-length="10" level="05" name="FS3B" picture="X(10)" position="12" storage-length="10"/>
        </item>
        <item display-length="6" level="03" name="FS4" position="22" storage-length="6">
            <item display-length="2" level="05" name="FS4A" numeric="true" picture="99" position="22" storage-length="2"/>
            <item display-length="2" level="05" name="FS4B" numeric="true" picture="99" position="24" storage-length="2"/>
            <item display-length="2" level="05" name="FS4C" numeric="true" picture="99" position="26" storage-length="2"/>
        </item>
        <item display-length="5" level="03" name="FS5" picture="X(5)" position="28" storage-length="5"/>
        <item display-length="20" level="03" name="FS6" picture="X(20)" position="33" storage-length="20"/>
        <item display-length="1" level="03" name="FS7" numeric="true" picture="9" position="53" storage-length="1"/>
        <item display-length="11" level="03" name="FS8" numeric="true" picture="S9(9)V99" position="54" scale="2" signed="true" storage-length="6" usage="computational-3"/>
        <item display-length="11" level="03" name="FS9" numeric="true" picture="S9(9)V99" position="60" scale="2" signed="true" storage-length="6" usage="computational-3"/>
        <item display-length="1" level="03" name="FS10" numeric="true" picture="9" position="66" storage-length="1"/>
        <item display-length="11" level="03" name="FS11" numeric="true" picture="S9(9)V99" position="67" scale="2" signed="true" storage-length="6" usage="computational-3"/>
        <item display-length="11" level="03" name="FS12" numeric="true" picture="S9(9)V99" position="73" scale="2" signed="true" storage-length="6" usage="computational-3"/>
        <item display-length="11" level="03" name="FS13" numeric="true" picture="S9(9)V99" position="79" scale="2" signed="true" storage-length="6" usage="computational-3"/>
        <item display-length="13" level="03" name="FS14-15" occurs="10" position="85" storage-length="13">
            <item display-length="1" level="05" name="FS14" numeric="true" picture="9" position="85" storage-length="1"/>
            <item display-length="11" level="05" name="FS15" numeric="true" picture="S9(9)V99" position="86" scale="2" signed="true" storage-length="6" usage="computational-3"/>
            <item display-length="11" level="05" name="FS16" numeric="true" picture="S9(9)V99" position="92" scale="2" signed="true" storage-length="6" usage="computational-3"/>
        </item>
        <item display-length="11" level="03" name="FS17" numeric="true" occurs="10" picture="S9(9)V99" position="215" scale="2" signed="true" storage-length="6" usage="computational-3"/>
        <item display-length="6" level="03" name="FS18" numeric="true" picture="9(6)" position="275" storage-length="6"/>
        <item display-length="1" level="03" name="FS19" numeric="true" picture="9" position="281" storage-length="1"/>

所有 XML 属性的列表

这里懒得复制粘贴我的VB.NET代码了,有注释清楚地解释了每个属性

      For Each Attribute As Xml.XmlAttribute In itemNode.Attributes

            Select Case Attribute.Name

                Case "name" ' FIeld name

                Case "level" ' PICTURE level

                Case "numeric"  ' True if numeric data type

                Case "picture" ' COmplete PICTURE string

                Case "storage-length" ' Variable storage lenght

                Case "usage" ' If COMP field, give the original COMP type ("computational-x")

                Case "signed" ' true if PIC S...

                Case "scale" ' Give number of digits afeter decimal point

                Case "redefined" ' true if the field is redifined afterwards

                Case "redefines" ' If REDEFINES : give the name of the redefined field

                Case "occurs" ' give the number of occurences if it's an ARRAY

                Case "position" ' Give the line position in the original copybook

                Case "display-length" ' Give the display size

                Case "filename" ' Give the FD name

在这种 XML 结构的帮助下,我已经实现了所有目标,甚至更多。

生成的 COBOL 程序将 索引文件(只能使用 RM cobol 运行时读取)转换为 平面文件,处理每个字段,包括 ARRAYS 和 REDEFINES。

  • 对于 REDEFINES:我为“主要”图片及其所有 REDEFINES 更改创建一个字段,并且它们的类型与其 COBOL PICTURE 匹配
  • 对于 ARRAY,我为每个元素创建了一个字段,并且还创建了一个包含整个数组“行”的巨大字段
  • 对于 COMPUTATIONAL 字段,我只是将原始 COMP 移动到完全相同的 DISPLAY PICTURE 中

并非所有字段在数据库中都有用途,但至少所有内容始终可用

有了上面的发票文件,SEQUENTIAL 文本文件字帖就变成了这样:

自动生成的 COBOL

  FILE SECTION. 

  * ----------------------------------------------------------- 
  * INPUT FILE                                                
       COPY "FD8.COP" . 

  * -----------------------------------------------------------
  * OUTPUT FILE
   FD FACTURE-DWH.
   01 REC-FACTURE-DWH.      
       03 FS1-DWH           PIC X.
       03 FS2-DWH           PIC X(9).
       03 FS2A-DWH           PIC 9.
       03 RFS2B-DWH           PIC X(8).
       03 FS2B-DWH           PIC 9(8).
       03 FS3-DWH           PIC X(11).
       03 FS3A-DWH           PIC 9.
       03 FS3B-DWH           PIC X(10).
       03 FS4-DWH           PIC X(6).
       03 FS4A-DWH           PIC 99.
       03 FS4B-DWH           PIC 99.
       03 FS4C-DWH           PIC 99.
       03 FS5-DWH           PIC X(5).
       03 FS6-DWH           PIC X(20).
       03 FS7-DWH           PIC 9.
       03 FS8-DWH           PIC -9(9)V99.
       03 FS9-DWH           PIC -9(9)V99.
       03 FS10-DWH           PIC 9.
       03 FS11-DWH           PIC -9(9)V99.
       03 FS12-DWH           PIC -9(9)V99.
       03 FS13-DWH           PIC -9(9)V99.
       03 FS14-15-1-DWH           PIC X(13).
       03 FS14-15-2-DWH           PIC X(13).
       03 FS14-15-3-DWH           PIC X(13).
       03 FS14-15-4-DWH           PIC X(13).
       03 FS14-15-5-DWH           PIC X(13).
       03 FS14-15-6-DWH           PIC X(13).
       03 FS14-15-7-DWH           PIC X(13).
       03 FS14-15-8-DWH           PIC X(13).
       03 FS14-15-9-DWH           PIC X(13).
       03 FS14-15-10-DWH           PIC X(13).
       03 FS14-1-DWH           PIC 9.
       03 FS14-2-DWH           PIC 9.
       03 FS14-3-DWH           PIC 9.
       03 FS14-4-DWH           PIC 9.
       03 FS14-5-DWH           PIC 9.
       03 FS14-6-DWH           PIC 9.
       03 FS14-7-DWH           PIC 9.
       03 FS14-8-DWH           PIC 9.
       03 FS14-9-DWH           PIC 9.
       03 FS14-10-DWH           PIC 9.
       03 FS15-1-DWH           PIC -9(9)V99.
       03 FS15-2-DWH           PIC -9(9)V99.
       03 FS15-3-DWH           PIC -9(9)V99.
       03 FS15-4-DWH           PIC -9(9)V99.
       03 FS15-5-DWH           PIC -9(9)V99.
       03 FS15-6-DWH           PIC -9(9)V99.
       03 FS15-7-DWH           PIC -9(9)V99.
       03 FS15-8-DWH           PIC -9(9)V99.
       03 FS15-9-DWH           PIC -9(9)V99.
       03 FS15-10-DWH           PIC -9(9)V99.
       03 FS16-1-DWH           PIC -9(9)V99.
       03 FS16-2-DWH           PIC -9(9)V99.
       03 FS16-3-DWH           PIC -9(9)V99.
       03 FS16-4-DWH           PIC -9(9)V99.
       03 FS16-5-DWH           PIC -9(9)V99.
       03 FS16-6-DWH           PIC -9(9)V99.
       03 FS16-7-DWH           PIC -9(9)V99.
       03 FS16-8-DWH           PIC -9(9)V99.
       03 FS16-9-DWH           PIC -9(9)V99.
       03 FS16-10-DWH           PIC -9(9)V99.
       03 FS17-1-DWH           PIC -9(9)V99.
       03 FS17-2-DWH           PIC -9(9)V99.
       03 FS17-3-DWH           PIC -9(9)V99.
       03 FS17-4-DWH           PIC -9(9)V99.
       03 FS17-5-DWH           PIC -9(9)V99.
       03 FS17-6-DWH           PIC -9(9)V99.
       03 FS17-7-DWH           PIC -9(9)V99.
       03 FS17-8-DWH           PIC -9(9)V99.
       03 FS17-9-DWH           PIC -9(9)V99.
       03 FS17-10-DWH           PIC -9(9)V99.
       03 FS18-DWH           PIC 9(6).
       03 FS19-DWH           PIC 9.

移动指令

  * ============================================================   
   PROG.                                                             
       MOVE FS1  TO FS1-DWH
       MOVE FS2  TO FS2-DWH
       MOVE FS2A  TO FS2A-DWH
       MOVE RFS2B  TO RFS2B-DWH
       MOVE FS2B  TO FS2B-DWH
       MOVE FS3  TO FS3-DWH
       MOVE FS3A  TO FS3A-DWH
       MOVE FS3B  TO FS3B-DWH
       MOVE FS4  TO FS4-DWH
       MOVE FS4A  TO FS4A-DWH
       MOVE FS4B  TO FS4B-DWH
       MOVE FS4C  TO FS4C-DWH
       MOVE FS5  TO FS5-DWH
       MOVE FS6  TO FS6-DWH
       MOVE FS7  TO FS7-DWH
       MOVE FS8  TO FS8-DWH
       MOVE FS9  TO FS9-DWH
       MOVE FS10  TO FS10-DWH
       MOVE FS11  TO FS11-DWH
       MOVE FS12  TO FS12-DWH
       MOVE FS13  TO FS13-DWH
       MOVE FS14-15(1)  TO FS14-15-1-DWH
       MOVE FS14-15(2)  TO FS14-15-2-DWH
       MOVE FS14-15(3)  TO FS14-15-3-DWH
       MOVE FS14-15(4)  TO FS14-15-4-DWH
       MOVE FS14-15(5)  TO FS14-15-5-DWH
       MOVE FS14-15(6)  TO FS14-15-6-DWH
       MOVE FS14-15(7)  TO FS14-15-7-DWH
       MOVE FS14-15(8)  TO FS14-15-8-DWH
       MOVE FS14-15(9)  TO FS14-15-9-DWH
       MOVE FS14-15(10)  TO FS14-15-10-DWH
       MOVE FS14(1)  TO FS14-1-DWH
       MOVE FS14(2)  TO FS14-2-DWH
       MOVE FS14(3)  TO FS14-3-DWH
       MOVE FS14(4)  TO FS14-4-DWH
       MOVE FS14(5)  TO FS14-5-DWH
       MOVE FS14(6)  TO FS14-6-DWH
       MOVE FS14(7)  TO FS14-7-DWH
       MOVE FS14(8)  TO FS14-8-DWH
       MOVE FS14(9)  TO FS14-9-DWH
       MOVE FS14(10)  TO FS14-10-DWH
       MOVE FS15(1)  TO FS15-1-DWH
       MOVE FS15(2)  TO FS15-2-DWH
       MOVE FS15(3)  TO FS15-3-DWH
       MOVE FS15(4)  TO FS15-4-DWH
       MOVE FS15(5)  TO FS15-5-DWH
       MOVE FS15(6)  TO FS15-6-DWH
       MOVE FS15(7)  TO FS15-7-DWH
       MOVE FS15(8)  TO FS15-8-DWH
       MOVE FS15(9)  TO FS15-9-DWH
       MOVE FS15(10)  TO FS15-10-DWH
       MOVE FS16(1)  TO FS16-1-DWH
       MOVE FS16(2)  TO FS16-2-DWH
       MOVE FS16(3)  TO FS16-3-DWH
       MOVE FS16(4)  TO FS16-4-DWH
       MOVE FS16(5)  TO FS16-5-DWH
       MOVE FS16(6)  TO FS16-6-DWH
       MOVE FS16(7)  TO FS16-7-DWH
       MOVE FS16(8)  TO FS16-8-DWH
       MOVE FS16(9)  TO FS16-9-DWH
       MOVE FS16(10)  TO FS16-10-DWH
       MOVE FS17(1)  TO FS17-1-DWH
       MOVE FS17(2)  TO FS17-2-DWH
       MOVE FS17(3)  TO FS17-3-DWH
       MOVE FS17(4)  TO FS17-4-DWH
       MOVE FS17(5)  TO FS17-5-DWH
       MOVE FS17(6)  TO FS17-6-DWH
       MOVE FS17(7)  TO FS17-7-DWH
       MOVE FS17(8)  TO FS17-8-DWH
       MOVE FS17(9)  TO FS17-9-DWH
       MOVE FS17(10)  TO FS17-10-DWH
       MOVE FS18  TO FS18-DWH
       MOVE FS19  TO FS19-DWH

一旦编写了平面文件,它们就可以通过 VBA 代码处理到 MySQL,也由 VB.NET 应用程序生成。


自动生成的 VBA

类型def声明处理文本文件导入

注意每个字段旁边的 cmets 中的原始图片

'-------------------------------------------------------------
' REC_FC8 Record
'-------------------------------------------------------------
Private Type REC_FC8 
   FS1 as string*1  '  03 FS1  PIC X  
   FS2 as string*9  '  03 FS2  PIC   
   FS2A as string*1  '  05 FS2A  PIC 9  
   RFS2B as string*8  '  05 RFS2B  PIC X(8)  
   FS2B as string*8  '  05 FS2B  PIC 9(8)  
   FS3 as string*11  '  03 FS3  PIC   
   FS3A as string*1  '  05 FS3A  PIC 9  
   FS3B as string*10  '  05 FS3B  PIC X(10)  
   FS4 as string*6  '  03 FS4  PIC   
   FS4A as string*2  '  05 FS4A  PIC 99  
   FS4B as string*2  '  05 FS4B  PIC 99  
   FS4C as string*2  '  05 FS4C  PIC 99  
   FS5 as string*5  '  03 FS5  PIC X(5)  
   FS6 as string*20  '  03 FS6  PIC X(20)  
   FS7 as string*1  '  03 FS7  PIC 9  
   FS8 as string*12  '  03 FS8  PIC S9(9)V99 computational-3 
   FS9 as string*12  '  03 FS9  PIC S9(9)V99 computational-3 
   FS10 as string*1  '  03 FS10  PIC 9  
   FS11 as string*12  '  03 FS11  PIC S9(9)V99 computational-3 
   FS12 as string*12  '  03 FS12  PIC S9(9)V99 computational-3 
   FS13 as string*12  '  03 FS13  PIC S9(9)V99 computational-3 
   FS14_15_1 as string*13  '  03 FS14-15  PIC   
   FS14_15_2 as string*13  '  03 FS14-15  PIC   
   FS14_15_3 as string*13  '  03 FS14-15  PIC   
   FS14_15_4 as string*13  '  03 FS14-15  PIC   
   FS14_15_5 as string*13  '  03 FS14-15  PIC   
   FS14_15_6 as string*13  '  03 FS14-15  PIC   
   FS14_15_7 as string*13  '  03 FS14-15  PIC   
   FS14_15_8 as string*13  '  03 FS14-15  PIC   
   FS14_15_9 as string*13  '  03 FS14-15  PIC   
   FS14_15_10 as string*13  '  03 FS14-15  PIC   
   FS14_1 as string*1  '  05 FS14  PIC 9  
   FS14_2 as string*1  '  05 FS14  PIC 9  
   FS14_3 as string*1  '  05 FS14  PIC 9  
   FS14_4 as string*1  '  05 FS14  PIC 9  
   FS14_5 as string*1  '  05 FS14  PIC 9  
   FS14_6 as string*1  '  05 FS14  PIC 9  
   FS14_7 as string*1  '  05 FS14  PIC 9  
   FS14_8 as string*1  '  05 FS14  PIC 9  
   FS14_9 as string*1  '  05 FS14  PIC 9  
   FS14_10 as string*1  '  05 FS14  PIC 9  
   FS15_1 as string*12  '  05 FS15  PIC S9(9)V99 computational-3 
   FS15_2 as string*12  '  05 FS15  PIC S9(9)V99 computational-3 
   FS15_3 as string*12  '  05 FS15  PIC S9(9)V99 computational-3 
   FS15_4 as string*12  '  05 FS15  PIC S9(9)V99 computational-3 
   FS15_5 as string*12  '  05 FS15  PIC S9(9)V99 computational-3 
   FS15_6 as string*12  '  05 FS15  PIC S9(9)V99 computational-3 
   FS15_7 as string*12  '  05 FS15  PIC S9(9)V99 computational-3 
   FS15_8 as string*12  '  05 FS15  PIC S9(9)V99 computational-3 
...
   FS17_8 as string*12  '  03 FS17  PIC S9(9)V99 computational-3 
   FS17_9 as string*12  '  03 FS17  PIC S9(9)V99 computational-3 
   FS17_10 as string*12  '  03 FS17  PIC S9(9)V99 computational-3 
   FS18 as string*6  '  03 FS18  PIC 9(6)  
   FS19 as string*1  '  03 FS19  PIC 9      
        FC8LF As String * 2 ' LF 11
End Type

创建表过程

每个字段都变成了一个对象(来自我创建的自定义类),下面使用的方法SQLtypeFull返回每个字段的MySQL数据类型

'========================================================================
Private Function Create_Table_MySQL() As Boolean
    On Error GoTo Erreur

    Dim Rs As Recordset
    Dim SQL As String

    SQL = "CREATE TABLE IF NOT EXISTS `TBL_DAT_FACTURE` ( `ID` INT(11) NOT NULL auto_increment, `RECID` INT(11)"
           SQL = SQL &  ", `FS1` " & FS1.SQLtypeFull
           SQL = SQL &  ", `FS2` " & FS2.SQLtypeFull
           SQL = SQL &  ", `FS2A` " & FS2A.SQLtypeFull
           SQL = SQL &  ", `RFS2B` " & RFS2B.SQLtypeFull
           SQL = SQL &  ", `FS2B` " & FS2B.SQLtypeFull
           SQL = SQL &  ", `FS3` " & FS3.SQLtypeFull
           SQL = SQL &  ", `FS3A` " & FS3A.SQLtypeFull
           SQL = SQL &  ", `FS3B` " & FS3B.SQLtypeFull
           SQL = SQL &  ", `FS4` " & FS4.SQLtypeFull
           SQL = SQL &  ", `FS4A` " & FS4A.SQLtypeFull
           SQL = SQL &  ", `FS4B` " & FS4B.SQLtypeFull
           SQL = SQL &  ", `FS4C` " & FS4C.SQLtypeFull
           SQL = SQL &  ", `FS5` " & FS5.SQLtypeFull
           SQL = SQL &  ", `FS6` " & FS6.SQLtypeFull
           SQL = SQL &  ", `FS7` " & FS7.SQLtypeFull
           SQL = SQL &  ", `FS8` " & FS8.SQLtypeFull
           SQL = SQL &  ", `FS9` " & FS9.SQLtypeFull
           SQL = SQL &  ", `FS10` " & FS10.SQLtypeFull
           SQL = SQL &  ", `FS11` " & FS11.SQLtypeFull
           SQL = SQL &  ", `FS12` " & FS12.SQLtypeFull
           SQL = SQL &  ", `FS13` " & FS13.SQLtypeFull
           SQL = SQL &  ", `FS14_15_1` " & FS14_15_1.SQLtypeFull
           SQL = SQL &  ", `FS14_15_2` " & FS14_15_2.SQLtypeFull
           SQL = SQL &  ", `FS14_15_3` " & FS14_15_3.SQLtypeFull
           SQL = SQL &  ", `FS14_15_4` " & FS14_15_4.SQLtypeFull
           SQL = SQL &  ", `FS14_15_5` " & FS14_15_5.SQLtypeFull
           SQL = SQL &  ", `FS14_15_6` " & FS14_15_6.SQLtypeFull
           SQL = SQL &  ", `FS14_15_7` " & FS14_15_7.SQLtypeFull
           SQL = SQL &  ", `FS14_15_8` " & FS14_15_8.SQLtypeFull
           SQL = SQL &  ", `FS14_15_9` " & FS14_15_9.SQLtypeFull
           SQL = SQL &  ", `FS14_15_10` " & FS14_15_10.SQLtypeFull
           SQL = SQL &  ", `FS14_1` " & FS14_1.SQLtypeFull
           SQL = SQL &  ", `FS14_2` " & FS14_2.SQLtypeFull
           SQL = SQL &  ", `FS14_3` " & FS14_3.SQLtypeFull
           SQL = SQL &  ", `FS14_4` " & FS14_4.SQLtypeFull
           SQL = SQL &  ", `FS14_5` " & FS14_5.SQLtypeFull
           SQL = SQL &  ", `FS14_6` " & FS14_6.SQLtypeFull
           SQL = SQL &  ", `FS14_7` " & FS14_7.SQLtypeFull
           SQL = SQL &  ", `FS14_8` " & FS14_8.SQLtypeFull
           SQL = SQL &  ", `FS14_9` " & FS14_9.SQLtypeFull
           SQL = SQL &  ", `FS14_10` " & FS14_10.SQLtypeFull
           SQL = SQL &  ", `FS15_1` " & FS15_1.SQLtypeFull
           SQL = SQL &  ", `FS15_2` " & FS15_2.SQLtypeFull
           SQL = SQL &  ", `FS15_3` " & FS15_3.SQLtypeFull
           SQL = SQL &  ", `FS15_4` " & FS15_4.SQLtypeFull
           SQL = SQL &  ", `FS15_5` " & FS15_5.SQLtypeFull
...
           SQL = SQL &  ", `FS17_9` " & FS17_9.SQLtypeFull
           SQL = SQL &  ", `FS17_10` " & FS17_10.SQLtypeFull
           SQL = SQL &  ", `FS18` " & FS18.SQLtypeFull
           SQL = SQL &  ", `FS19` " & FS19.SQLtypeFull


    SQL = SQL & ", PRIMARY KEY (`ID`)"
    SQL = SQL & ") ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE utf8_bin;"
    MySQLcon.Execute (SQL)      

    Create_Table_MySQL = True

Exit_Sub:
    Exit Function

Erreur:
    Create_Table_MySQL = False
    Resume Exit_Sub

End Function

最终的 SQL 语句

CREATE TABLE IF NOT EXISTS `FACTURE` 
( `ID` INT(11) NOT NULL auto_increment, `RECID` INT(11), `FS1` CHAR(1), `FS2` CHAR(9), `FS2A` TINYINT(1) UNSIGNED, `RFS2B` CHAR(8), `FS2B` INT(8) UNSIGNED, `FS3` CHAR(11), `FS3A` TINYINT(1) UNSIGNED, `FS3B` CHAR(10), `FS4` CHAR(6), `FS4A` TINYINT(2) UNSIGNED, `FS4B` TINYINT(2) UNSIGNED, `FS4C` TINYINT(2) UNSIGNED, `FS5` CHAR(5), `FS6` CHAR(20), `FS7` TINYINT(1) UNSIGNED, `FS8` DECIMAL(11,2), `FS9` DECIMAL(11,2), `FS10` TINYINT(1) UNSIGNED, `FS11` DECIMAL(11,2), `FS12` DECIMAL(11,2), `FS13` DECIMAL(11,2), `FS14_15_1` CHAR(13), `FS14_15_2` CHAR(13), `FS14_15_3` CHAR(13), `FS14_15_4` CHAR(13), `FS14_15_5` CHAR(13), `FS14_15_6` CHAR(13), `FS14_15_7` CHAR(13), `FS14_15_8` CHAR(13), `FS14_15_9` CHAR(13), `FS14_15_10` CHAR(13), `FS14_1` TINYINT(1) UNSIGNED, `FS14_2` TINYINT(1) UNSIGNED, `FS14_3` TINYINT(1) UNSIGNED, `FS14_4` TINYINT(1) UNSIGNED, `FS14_5` TINYINT(1) UNSIGNED, `FS14_6` TINYINT(1) UNSIGNED, `FS14_7` TINYINT(1) UNSIGNED, `FS14_8` TINYINT(1) UNSIGNED, `FS14_9` TINYIN
T(1) UNSIGNED, `FS14_10` TINYINT(1) UNSIGNED, `FS15_1` DECIMAL(11,2), `FS15_2` DECIMAL(11,2), `FS15_3` DECIMAL(11,2), `FS15_4` DECIMAL(11,2), `FS15_5` DECIMAL(11,2), `FS15_6` DECIMAL(11,2), `FS15_7` DECIMAL(11,2), `FS15_8` 
...
DECIMAL(11,2), `FS17_10` DECIMAL(11,2), `FS18` DATE, `FS19` TINYINT(1) UNSIGNED, 
 PRIMARY KEY (`ID`)) ENGINE=MyISAM  
 DEFAULT CHARSET=utf8 COLLATE utf8_bin;

我在生成的 VBA 模块中有更多内容,生成的 xml 的详细程度和准确性对所有这些模块都有很大帮助:

  • 我创建了一个类来管理字段的所有方面,特别是按照原始 PICTURE 和 VBA 类型(日期、长整数、双精度数、货币等)处理 VBA/MySQL 的转换,并且有一个钩子以防您想强制使用其他类型。
  • 它完全处理元数据的创建(也在 MySQL 中)
  • 它处理导入数据时的错误,在文件和字段级别记录所有内容

我可能已经展示了足够多的东西来给你一些想法,所以我会停在那里。

最重要的是:当我们将 COBOL ERP 中进行的复杂计算转换为针对新数据仓库运行的 SQL 语句时,DB 返回的数字与 ERP 中返回的数字完全相同。在数百万条记录中,计算上没有一位数的损失。这是证明它有效的最好方法:-)

如果您想知道为什么我使用 Access/VBA 而不是 .NET 进行导入:这是一个不可协商的要求。

最后一点:我与 CB2XML 没有任何关系,这不是它的广告。这只是一个很棒且有用的软件,值得关注。

【讨论】:

  • 这在我的家用电脑上运行得非常好,但不幸的是我无法在我的工作电脑上安装 JDK...
  • @DanielDennis 我不知道你在哪家公司工作,但坦率地说,对于这种项目,使用 Java 获得开发和生产机器应该不是问题,或者你的公司不认真。
  • 我对它们做了一点小错误,我把它弄到了那里,所以我们现在都很好!
  • 再次非常感谢您!
  • 很好奇,当您不得不处理这个问题时,您是否还必须读取和转换可变长度的平面文件?或者只是固定长度。
【解决方案2】:

REDEFINES 会让你的任务变得更加困难。不是“编译器”知道使用哪个特定字段,直观地说,是现有 COBOL 系统中的代码知道使用哪个字段。会有一些指示,另一个字段中的一些值,它将指示在哪个特定时间使用哪个字段。

以你的第二个例子为例,因为第一个没有上下文:

05  ADDRESS-PO-BOX-FLAG                  PIC X.

在使用数据之前将询问该字段。直接(您可以在那里找到很多可怕的代码)或使用 88 级条件名称:

    88  ADDRESS-IS-A-PO-BOX              VALUE "Y". (an example only)

IF ADDRESS-IS-A-PO-BOX
    some code relating to PO Boxes
ELSE
    some code relating to other types of addresses
END-IF

将以类似的方式处理您的第一个示例。

这是 REDEFINES 的“旧式”用法,用于在互斥情况下使用记录上的相同存储位置。节省存储,这是昂贵的。您正在使用的系统要么是“旧的”,要么是它的设计被虚假的“经验”感染。

您有两个广泛的选择:复制所有有条件的数据选择(以便您有两组业务逻辑保持同步);更改文件,以便每个字段占用自己的存储空间。

COMP-3(或 PACKED-DECIMAL)或 COMP/COMP-4/COMP-5/BINARY 数据类型的存在也会使事情变得复杂。然后,您需要在字段级别针对实际的 EBCDIC 数据执行 EBCDIC 到 ASCII,并执行任何必要的操作来转换或简单地获取“计算”数据。

还要注意,任何带符号的显示数字字段(带有以 S 开头但没有明确“计算”用法的 PICture 的数字字段)显然在最后一个字节中包含“字符”数据,因为符号被持有作为最后一个字节的“overpunch”。

请注意,二进制数据类型将是 Big Endian。

如果您收到的文件没有 REDEFINES、没有“计算”字段和嵌入符号(或隐式小数位),这对您来说会变得非常简单。您的所有数据都是字符,您可以在记录级别(或在文件级别,使用您的文件传输机制)进行 EBCDIC 到 ASCII。

如果您查看此处标记为 COMP-3 的问题,您会发现对此的进一步讨论,并且如果您认为荒谬的路线(您的程序理解本机 Mainframe COBOL 数据项而不是纯“文本”)是唯一可行的方法,那么讨论中的许多内容可能对您有用并且可以使用或应用。

如果您的公司受到外部“监管”,那么在编写一行代码之前,请确保您的合规、审计和会计部门对您的设计感到满意。哎呀。迟到了。让我们希望它正在制造。

【讨论】:

  • 首先是的......我正在处理的 COBOL 文件是 1988 年的......而且它已经更新了,但是更多的补丁工作然后是完全拆除。跨度>
  • 正确的不是我的程序读取 cobol 文件并将其转换为我可以轻松使用和解释的内容(它显示此信息并且您可以轻松编辑它)。从那里您上传一个数据文件并按记录级别转换记录(计算字段非常容易计算以及发生关键字)。转换压缩数字后,最后一个字符是 C 表示正数,D 表示负数。 REDEFINES是我想不通的东西,我的问题主要来自于缺乏了解cobol和没有大型机经验
  • 在获取文件更改方面也是如此......不幸的是,在一个由遗留系统主导的更大业务中,我是一个很小的棋子
  • '88 并没有那么旧 :-) COBOL 系统中的某个地方是“逻辑”,它决定了在何时使用 REDEFINES 中直接和间接涉及的哪些字段。请不要对标志感到厌烦。签名字段应该有 C 或 D,但是,特别是在较差的系统上,您可能会看到 F,甚至 A、B 和 E 也是有效的。如果您获得文本数据,您的生活将变得轻松,无需重新定义。如果它是一个金融系统,我提到的那些人必须参与其中,他们很可能会决定(他们有权力)你被赋予了这一点。
  • 是的,它是一个金融系统,所以我至少会尝试了解它们,非常感谢!
猜你喜欢
  • 1970-01-01
  • 2019-09-22
  • 2014-09-14
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多