【问题标题】:Why would i get a SB37 error on the code?为什么我的代码会出现 SB37 错误?
【发布时间】:2014-03-17 17:49:01
【问题描述】:

我正在更改定义为 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.                 

当我去检查我的匹配项时,我发现我的 write 语句在我的所有常规文件行之间插入了一个空行。这里应该发生的唯一想法是在 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.   

【问题讨论】:

    标签: cobol jcl


    【解决方案1】:

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

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

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

    回到之前的答案。这将是非常混乱的......

    现在我们可以看到您的原始记录,您有 OCCURS ... DEPENDING ON ... 这使得原始文件在从 COBOL 程序写入时包含可变长度记录。

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

    我不会将 CTR 设置为压缩十进制字段,而是将其设置为二进制 (BINARY/COMP/COMP-4) 但这不是您可以更改的,并且不要以任何不同的方式定义你的布局版本,否则会发生非常奇怪的事情。

    猜测:

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

    通常有三种方法来处理这个问题:在记录中设置 OCCURS DEPENDING ON,在记录中使用一个值表示某事发生了多少次;在 FD 上使用 VARYING DEPENDING ON;在 FD 下使用不同的记录布局,多个 01 级别。

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

    随着我们变得更有经验,我们会使用 COPY 和字帖。如果定义了数百个字段但只使用了几个字段,那根本不是问题。使用抄写本,我们不需要检查位置,因为我们知道我们拥有与处理该数据的每个程序相同的位置。编写自己的布局是错误的方向。

    【讨论】:

    • 它有时会运行,但大部分情况下都会给我所有坏数据。与我一起工作的另一个人告诉我在我的 JCL SYSIN dd dsn=sw.t10.prime.filename,disp=(,CATLG),DCB=(LRECL=1500,RECFM=FB,BUFNO=25),RETPD= 中使用40,MGMTCLASS=TMM
    • 即使设置为只读取一条记录,然后将相同的记录写入文件,仍然会收到错误数据。把垃圾扔到田里。
    • 您使用的是 WRITE 还是 WRITE ... FROM ... ?如果只是 WRITE,您是否将数据移动到 WRITE 之前的输出记录?
    • 写入 O-PROVIDER-RECORD END-WRITE。
    • 您如何将数据输入 O-PROVIDER-RECORD?
    猜你喜欢
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多