Java映射COBOL comp和comp-3字段

5

我正在从我的Java应用程序中调用使用COBOL创建的DB2存储过程。

输入宏(类型为varchar):

01 SP1-INPUTS.
    05 FIELD-1      PIC X(03).
    05 FIELD-2      PIC S9(09) COMP.
    05 FIELD-3      PIC S9(15)V9(02) COMP-3.
    05 FIELD-3X     REDEFINES  FIELD-3 PIC X(09)

为了测试存储过程,我只知道FIELD-1的值。对于其他字段,为了填充压缩部分,我应该放多少个零?请参考我写的代码并在传递虚拟值时感到困惑。

String field1="abc";
String field2="000000000"; // 9 zeroes, correct?
String field3="00...0" // should I give 18 zeroes or 9 zeroes?

输入宏总共需要多少个字符?

DB2 for z/OS还是LUW?你的JAVA在哪里运行? - Bill Woodger
DB2 for z/OS。Java应用正在我的本地机器上运行。 - Sridhar
1个回答

5
COBOL没有字符串,而是具有没有终止符的固定长度字段。
因此,对于FIELD-1,您有三个“字符”。X的图像可以允许256个可能的位值,但通常包含可读的值。
FIELD-2是二进制字段。您可以将其视为四字节整数。
然而,在这里定义它的方式是COMP,带有S,其最大值为999,999,999正值和999,999,999负值。
如果将其定义为COMP-5,则可以包含这四个字节中所有位的完整范围。注意,编译器选项TRUNC(BIN)会修改COMP到COMP-5的行为,因此您需要与Mainframe方面检查使用了哪个编译选项进行TRUNC(其他值为STD和OPT)。
在IBM Mainframe上,本机二进制字段为Big Endian。在您的本地计算机上,本机二进制值将是Little Endian。例如,值为16906090将存储为X'01020304'。
FIELD-3是压缩十进制。它长九个字节,但每个字节都包含两个十进制数字,除了低序(最右边)字节,其中包含一个数字,后跟一个符号说明符(图片使用S,因此正数应为C,负数应为D,基数为16)。有一个隐含的小数点(V)和两个小数位。
FIELD-3X是另一个X字段。它可以再次包含每个字节中的任何位模式。您需要知道该字段的预期用途(与其他字段一样,名称中甚至没有最小的线索,这是一种不好的做法)。
设计是错误的。从Mainframe发送二进制和压缩十进制字段到其他地方或反之亦然是完全疯狂的。如果所有字段都定义为没有COMP或COMP-3 USAGE(隐含),那么您将非常轻松。
最后一个定义缺少必需的句点/周期,但这可能是打字错误。
   01  SP1J-INPUTS. 
       05  a-meaningful-name               PIC X(03). 
       05  another-meaningful-name         PIC S9(09) 
                                            SIGN LEADING SEPARATE.
       05  a-third-meaningful-name         PIC +9(15).9(02). 
       05  yet-annother-meaningful-name 
           REDEFINES a-third-meaningful-name 
                                           PIC X(19). 

这里展示了两种处理符号的方法,一种是使用SIGN子句,另一种是使用数值编辑定义。在数值编辑定义中,.是一个实际的十进制点,而不是一个暗含的点,其中包含V。
现在所有的数据都是“文本”或“字符”数据,这对您来说应该很容易处理。将EBCDIC(IBM大型机编码)转换为ASCII(您的本地计算机编码,可能)很容易,并且可以在数据级别而不是字段级别上完成。
对于你们的来回通信,上述方式对你来说会更容易,错误率更低,审计也更容易。在内部,COBOL程序可以轻松地进行自己内部使用的转换。
如果你没能让他们把你的接口改成“字符”,那么你将需要做各种额外的编码和测试工作,但并没有任何优势。
一个包含ABC、123456789(负数)和123456789012345.67(正数)的布局示例如下:
ABC-123456789+123456789012345.67

请注意,除了没有字段分隔符之外,也没有数据/记录分隔符。没有“null”。
还有一种替代实际小数点的方法,那就是提供一个缩放因子。此外,您可以在程序中“硬编码”缩放。
我假设上述数据对您来说既容易接受又容易创建。请尝试更改您的接口。如果他们拒绝,请向您的老板记录额外代码的影响,以及在甚至考虑使用数据之前,需要“理解”数据的额外代码。这很愚蠢。
为了为您创建易于格式化的数据,COBOL程序需要执行以下操作:
MOVE FIELD-1                  TO a-meaningful-name 
MOVE FIELD-2                  TO another-meaningful-name
MOVE FIELD-3                  TO a-third-meaningful-name

为了从您那里接收易于格式化的数据,COBOL程序需要执行以下操作:
MOVE a-meaningful-name        TO FIELD-1 
MOVE another-meaningful-name  TO FIELD-2     
MOVE a-third-meaningful-name  TO FIELD-3

如果REDEFINES有用途,那么第四个字段需要特定的代码,但是我很难猜出来,一旦实际需求得到满足,编写代码并不困难。这并不困难,比你需要编写的其他代码要简单得多。

另一种可能更符合Java习惯的方法是使用XML将数据传递给存储过程。正如Bill所知道的,但其他读者可能不知道的那样,IBM的企业COBOL可以本地解析XML。 - cschneid
@cschneid 不错的主意。也许如果他们看到<FIELD-1>abc</FIELD-1><FIELD-2>12345</FIELD-2>,会鼓励使用除了FIELD-1之外的名称……或许我不够愤世嫉俗:-)正如你所说,输入/输出也很容易。三四个字段,开销不大。哦,还有那个未解释的REDEFINES,但解释一下就行了…… - Bill Woodger
帮助我很多,让我更好地理解了!谢谢。 - Sridhar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接