为什么我会在代码上出现SB37错误?

时间:2014-03-17 17:49:01

标签: cobol jcl

我正在更改定义7500字节的文件中的三个值。我曾经将所有文件定义放在我的文件之后,以便我能更好地看到它。但是,由于我已经提升了COBOL的水平,我只想让所有东西成为填充物,然后让我需要访问的四个字段可见。

当我运行JCL时,我一直收到sB37错误。我的输出文件也被定义为7500字节。我查看了编译列表,它在正确的位置显示了我的所有字段。

我查看了我的输出文件,似乎只写了28,000条记录,前十条看起来有一些垃圾信息。

我无法列出公司规则的整个程序,但我将如何解决sB37错误。

问题:如何解决sB37错误?

代码:

FD OUTPUT-FILE                                   
     RECORD VARYING FROM 2900 TO 7500          
     RECORDING MODE IS V                       
     BLOCK CONTAINS 0.                         
 01 O-PROVIDER-RECORD.                            
     05 FILLER              PIC X(149).           
     05 END-DTE             PIC X(8).             
     05 CANCEL              PIC X(2).             
     05 FILLER              PIC X(1133).          
     05 LAST-ACTIVITY-DTE   PIC X(8).             
     05 FILLER              PIC X(1598).          
     05 GROUP-CTR           PIC S999 COMP-3.      
     05 FILLER              PIC X(4600).  

JCL:

//STEP2      EXEC PGM=programnamehere             
//STEPLIB     DD DSN=SW89.DEBUG.programnamehere,DISP=SHR                 
//SYSOUT      DD SYSOUT=1                                         
//SYSDBOUT    DD SYSOUT=1                                         
//SYSOUC      DD SYSOUT=2                                         
//SYSPRINT    DD SYSOUT=1                                         
//SYSUDUMP    DD SYSOUT=1                                         
//INPUT1      DD DSN=MainFile.B01(+0),DISP=SHR,BUFNO=30               
//INPUT2      DD DSN=CDP.PARMLIB(SW00T111),DISP=SHR               
//OUTPUT1     DD DSN=SW89.DEBUG.OUTPUTFILE,DISP=(NEW,CATLG),             
//            DCB=TS20.VB7504.MODEL,MGMTCLAS=TMM,                 
//            SPACE=(CYL,(100,10),RLSE)                           
//PRTOUTA     DD SYSOUT=3,DCB=(BLKSIZE=0,LRECL=133,RECFM=FBM)     
//*         

档案的最后部分:

 05  AREA.                                                    
     10  IND                     PIC X.                 
     10  CTR                     PIC S999  COMP-3.      
    10 P-GROUP-INFO OCCURS 200 TIMES DEPENDING ON CTR.
         15  P-NO                PIC 9(7).              
         15  P-START-DTE.                                
             20  PSTART-CC       PIC 99.                 
             20  P-START-DATE.                           
                 25  P-START-YY  PIC 99.                 
                 25  P-START-MM  PIC 99.                 
                 25  P-START-DD  PIC 99.                 
         15  P-STOP-DTE.                                 
             20  P-STOP-CC       PIC 99.                 
             20  P-STOP-DATE.                            
                 25  YY          PIC 99.                 
                 25  MM          PIC 99.                 
                 25  DD          PIC 99.                 

当我去检查我的匹配时,我发现我的写声明在所有常规文件行之间插入一个空行。这里应该发生的唯一想法是在o-provider-record中更改了三个值,然后将其写回文件。每隔一行都不应该有这些新信息的空行。

代码:

CHECK-MATCH.                                                     
    PERFORM VARYING SUB FROM 1 BY 1 UNTIL SUB > TABLECOUNTER     
      IF P-PROVIDER >= TRIG-PROV-FROM(SUB) AND                   
         P-PROVIDER <= TRIG-PROV-THRU(SUB) THEN                  
         IF WS-CURRENT-DATE < P-END-DTE THEN                     
            IF P-YTD-TOTAL-PD  = 0 AND                           
               P-PYR-TOTAL-PD  = 0 AND                           
               P-PYR2-TOTAL-PD = 0 AND                           
               P-PYR3-TOTAL-PD = 0 AND                           
               P-PYR4-TOTAL-PD = 0 THEN                          
               IF P-NON-BILL-IND NOT EQUAL 'Y'                   
                PERFORM VARYING TAB FROM 1 BY 1 UNTIL TAB > 5    
                 IF P-TAXONOMY-CD(TAB) = TRIG-TAXONOMY(SUB) THEN 

                    ADD 1 TO T-REC-FOUND                       
                    ADD 1 TO T-REC-UPDATED                     

                    MOVE 'ZZ' TO O-CANCEL                      
                    MOVE '93939393' TO O-END-DTE               
                    MOVE '93939393' TO O-LAST-ACTIVITY-DTE    

                    PERFORM LOAD-PRINT-REPORT THRU X-LPR       
                    PERFORM PRINT-REPORT      THRU X-PR        
                    PERFORM ERASE-REPORT      THRU X-ER        
                 END-IF                                        
                END-PERFORM                                    
               END-IF                                          
            END-IF                                             
         END-IF                                                
      END-IF                                                   
     ADD 1 TO T-REC-WRITTEN              
     WRITE O-PROVIDER-RECORD END-WRITE   
    END-PERFORM.                         
X-CHECK-MATCH. EXIT.   

1 个答案:

答案 0 :(得分:4)

您正在为最外层PERFORM的每次迭代编写输出记录。如果有两次迭代(怀疑来自您之前的问题),那么对于每个输入记录,您将获得两个输出记录。

我们知道您的文件包含可变长度记录。从您描述的行为中,您没有对该文件使用APPLY WRITE,因此行为符合预期。 COBOL将FD / 01指向输出缓冲区中的下一个可用位置,首先是在OPEN之后,然后是在每次成功写入之后。 PERFORM循环中的第一个WRITE将指针移动到下一个可用位置,该位置包含作为起始点的任何旧东西,恰好位于其周围(对于早期的WRITE,它可能是二进制零,如缓冲区被重用,它将是你的旧数据。)

你需要进行一些重组,正如NealB在之前的问题上所建议的那样。你有很多在循环中“不变”的测试。它们应该在外面,并且只有在那些不变测试显示在这种情况下需要循环的可能性时才进入循环。

回到之前的答案。这将是非常令人困惑的......

现在我们可以看到你的原始记录了,你有OCCURS ...依赖...这就是当从COBOL程序写入时原始文件包含可变长度记录的原因。

如果在定义中包含相同的计数大小和位置,并且具有长度为23字节的条目的OCCURS,则将使记录变量的该部分的长度从零到4600字节(您的CTR替换为值为零到200)。

我没有让CTR成为压缩十进制字段,我已经把它变为二进制(BINARY / COMP / COMP-4),但这不是你可以改变的东西,并且没有任何不同的定义你的布局版本,否则会发生很奇怪的事情。

猜测:

你有RECORD [IS]变化......但你没有任何东西可以改变特定记录布局的长度。

通常有三种方法可以解决这个问题:在记录中有OCCURS DEPENDING ON,记录中较早的值表示事件发生的次数;在FD上使用VARYING DEPENDING ON;在FD下使用不同的记录布局,多个01级。

使用01编写的所有记录长度为7504字节。如果您的输入略低于此值,则输出数据集大小可能会更大,占用更多空间,并且每条记录的尾部可能包含有趣的值 - 与实际数据无直接关系。

随着我们变得更有经验,我们使用COPY和copybook。如果定义了数百个字段但只使用了少量字段,则根本不是问题。使用副本,我们不需要检查位置,因为我们知道每个程序处理该数据都一样。编写自己的布局是错误的方向。