我可以帮助您,因为2年前我完成了与您现在正在做的完全相同的事情。
我必须设计一个MySQL数据仓库,包括ETL系统,仅基于运行在Linux上的RM COBOL ERP应用程序中的文件。该应用程序有超过600个文件,并且尚不清楚其中多少最终会出现在数据库中。大多数重要文件都已索引,在COMP字段上进行索引以增加难度,其中一个明显的要求是所有文件之间的关系及其索引键都能在数据库中重现。因此,我可能需要每个文件的每个字段。
考虑到文件数量,手动逐个处理所有文件是不可行的。
我只看到了解决问题的一个实际方法:应用自动编程。即编写一个程序,从一个源(cobol copybooks)生成程序。
客户对我允许使用的技术有一些限制。我最终使用了一个VB.NET应用程序作为输入COBOL复制本,并:
- 生成COBOL程序,将原始索引文件中的数据转换为可利用的内容,并将记录写入顺序文本文件。
- 生成VBA模块,包括CREATE TABLE和Indexes,其中包含将这些数据文件从MS Access导入到MySQL所需的所有代码
在项目开始时,我遇到了与您现在完全相同的问题,特别是那些该死的REDEFINES。如果不是不可能,至少也是危险的任务,列出和编码所有复制簿可能性。
因此,我寻找另一种方式,并找到了这个:
CB2XML
COBOL复制簿转换为XML转换器:SourceForge
这为我节省了数周的复制簿解析和解释工作。
它可以解析COBOL复制簿,将其更改为描述所有PICTURE的XML文件,并具有许多有用的属性,例如长度或类型。它完全支持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"
Case "level"
Case "numeric"
Case "picture"
Case "storage-length"
Case "usage"
Case "signed"
Case "scale"
Case "redefined"
Case "redefines"
Case "occurs"
Case "position"
Case "display-length"
Case "filename"
有了这个XML结构,我已经实现了所有目标,甚至超出了预期。
生成的COBOL程序将只能使用RM Cobol运行时读取的“索引文件”转换为“平面文件”,并处理每个字段,包括数组和重新定义。
- 对于重新定义:我为“主”PICTURE和其所有重新定义变体创建一个字段,并且它们的类型与它们的COBOL PICTURE匹配
- 对于数组,我为每个元素创建一个字段,并且还创建一个包含整个数组“行”的巨大字段
- 对于计算字段,我只需将原始COMP移动到完全相同的DISPLAY PICTURE中
并非所有字段在数据库中都具有目的,但至少一切都随时可用。
对于上面的发票文件,顺序文本文件复制本变成了这样:
自动生成的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
一旦平面文件被写入,它们可以通过由VB.NET应用程序生成的VBA代码处理到MySQL。
自动生成的VBA代码
类型定义声明用于处理文本文件导入
请注意每个字段旁边的注释中原始的PICTURE
Private Type REC_FC8
FS1 as string*1
FS2 as string*9
FS2A as string*1
RFS2B as string*8
FS2B as string*8
FS3 as string*11
FS3A as string*1
FS3B as string*10
FS4 as string*6
FS4A as string*2
FS4B as string*2
FS4C as string*2
FS5 as string*5
FS6 as string*20
FS7 as string*1
FS8 as string*12
FS9 as string*12
FS10 as string*1
FS11 as string*12
FS12 as string*12
FS13 as string*12
FS14_15_1 as string*13
FS14_15_2 as string*13
FS14_15_3 as string*13
FS14_15_4 as string*13
FS14_15_5 as string*13
FS14_15_6 as string*13
FS14_15_7 as string*13
FS14_15_8 as string*13
FS14_15_9 as string*13
FS14_15_10 as string*13
FS14_1 as string*1
FS14_2 as string*1
FS14_3 as string*1
FS14_4 as string*1
FS14_5 as string*1
FS14_6 as string*1
FS14_7 as string*1
FS14_8 as string*1
FS14_9 as string*1
FS14_10 as string*1
FS15_1 as string*12
FS15_2 as string*12
FS15_3 as string*12
FS15_4 as string*12
FS15_5 as string*12
FS15_6 as string*12
FS15_7 as string*12
FS15_8 as string*12
...
FS17_8 as string*12
FS17_9 as string*12
FS17_10 as string*12
FS18 as string*6
FS19 as string*1
FC8LF As String * 2
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文件的详细程度和准确性对它们所有都有很大帮助:
- 我创建了一个类来管理字段的所有方面,特别是处理VBA/MySQL之间的转换,遵循原始的PICTURE和VBA类型(日期、长整型、双精度浮点型、货币等),如果需要强制使用其他类型,则可以使用钩子。
- 它完全处理元数据的创建(也适用于MySQL)
- 它处理导入数据时的错误,将所有内容记录在文件和字段级别上
我已经展示了足够的内容,以便给你一些想法,所以我就到这里吧。
最重要的是:当我们将COBOL ERP中进行的复杂计算转化为针对新数据仓库运行的SQL语句时,数据库返回的数字与ERP中的数字完全相同。在数百万条记录中,没有一个数字损失计算。这是证明它有效的最好方法 :-)
如果你想知道我为什么使用Access/VBA而不是.NET进行导入:这是一个不可谈判的要求。
最后注意一点:我与CB2XML没有任何关联,这不是宣传它的广告。它只是一款非常好用和有用的软件,值得一提。