☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

Mostrar mensagens com a etiqueta return code. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta return code. Mostrar todas as mensagens

sexta-feira, 9 de janeiro de 2026

💥 FILE STATUS 00… E MESMO ASSIM DEU RUIM? — O LADO SOMBRIO DO VSAM QUE NINGUÉM TE CONTA

Bellacosa Mainframe VSAM e seus File Status


💥 FILE STATUS 00… E MESMO ASSIM DEU RUIM? — O LADO SOMBRIO DO VSAM QUE NINGUÉM TE CONTA

Se você acha que FILE STATUS = só checar 00 e seguir a vida, prepare-se:
👉 é exatamente assim que nascem os bugs mais caros do mainframe.

Hoje vamos abrir a caixa preta do VSAM FILE STATUS no estilo Bellacosa:
sem romantismo, direto na ferida — código, causa e como sair vivo.


🧠 O QUE É FILE STATUS (DE VERDADE)

FILE STATUS é um campo de 2 bytes no COBOL que retorna o resultado de TODA operação de I/O.

💣 Tradução real:

É o único contrato entre seu programa e o VSAM. Ignorou… perdeu o controle.


🔢 MAPA COMPLETO DOS FILE STATUS (VSAM COBOL)

Vamos direto ao que interessa.


✅ SUCESSO (OU QUASE…)

CódigoSignificadoTradução BellacosaAção
00Sucesso“Tudo certo… por enquanto”OK
02Sucesso com duplicidade permitidaRegistro duplicado aceitoValidar regra de negócio

📭 FIM / NÃO ENCONTRADO

CódigoSignificadoTraduçãoAção
10End of FileAcabouFluxo normal
13Nenhum próximo registroCursor inválidoVer START
23Registro não encontrado“Você pediu algo que não existe”Validar chave
35Dataset não encontrado“Você abriu algo que não existe”Ver catálogo

💥 Clássico:

FS=23 não é erro técnico — é erro de lógica.


🔁 DUPLICIDADE / CHAVE

CódigoSignificadoTraduçãoAção
22Duplicate keyJá existeTratar insert
24Boundary violationFora do rangeValidar chave
21Sequência inválidaOrdem erradaOrdenação errada

💣 Esse trio derruba batch inteiro.


⚙️ ERROS DE ACESSO / LÓGICA

CódigoSignificadoTraduçãoAção
34Boundary violation (ESDS/RRDS)Fora do espaçoAjustar definição
41OPEN já executadoReabriu arquivoRevisar fluxo
42CLOSE em arquivo não abertoBagunça de controleAjustar lógica
43REWRITE sem READAtualizando fantasmaCorrigir fluxo
44Record size mismatchLayout erradoRevisar copybook

💥 Esse grupo é:

erro de programador raiz


🔒 LOCK / CONCORRÊNCIA (O TERROR DO ONLINE)

CódigoSignificadoTraduçãoAção
91Lock timeout/deadlock“Outro job está na sua frente”Retry
92Logic errorAcesso inconsistenteRevisar fluxo
93Resource unavailableRecurso indisponívelEsperar/retry

💣 Aqui entra:

  • CICS
  • RLS
  • Batch concorrente

👉 Esse é o mundo real.


💾 ERROS FÍSICOS / INFRA

CódigoSignificadoTraduçãoAção
90Erro geral“Algo deu muito errado”Ver log
94Falha em READ/WRITEProblema físicoVer dataset
97Erro de VSAMFalha internaAnalisar IDCAMS
98File lockedDataset travadoVer enqueue

💥 Tradução:

Aqui você chama o sysprog.


🧨 OS CÓDIGOS QUE MAIS CAEM EM PRODUÇÃO

Top 5 do caos:

  1. 23 → registro não encontrado
  2. 22 → duplicate key
  3. 10 → EOF mal tratado
  4. 91 → lock em produção
  5. 44 → layout errado

👉 Se você nunca viu esses… você ainda não sofreu o suficiente.


🧪 EXEMPLO COBOL (DO MUNDO REAL)

READ ARQ-VSAM
AT END
MOVE '10' TO WS-FS
NOT AT END
CONTINUE
END-READ

IF WS-FS NOT = '00' AND WS-FS NOT = '10'
DISPLAY 'ERRO VSAM: ' WS-FS
PERFORM TRATA-ERRO
END-IF

💡 Bellacosa insight:

Nunca trate só 00. Sempre trate o resto.


⚠️ ARMADILHAS QUE DERRUBAM SISTEMA

🔥 Ignorar FILE STATUS
🔥 Não tratar 23
🔥 Não prever retry para 91
🔥 REWRITE sem READ
🔥 Layout diferente do VSAM

💣 Resultado:

  • dados inconsistentes
  • batch quebrado
  • incidente em produção

🧠 DICAS DE GUERRA (OU SOBREVIVÊNCIA)

✔ Sempre logar FILE STATUS
✔ Criar tabela de tratamento centralizado
✔ Retry inteligente para 91/93
✔ Validar chave antes de acessar
✔ Testar concorrência

👉 E a regra de ouro:

💥 FILE STATUS não é detalhe. É arquitetura.


🧨 EASTER EGG (PRA QUEM É RAIZ)

👉 FILE STATUS 00 não garante sucesso lógico
👉 VSAM pode retornar sucesso e ainda assim você estar lendo dado errado

Sim…

💣 O erro pode ser silencioso


🔥 VSAM RETURN CODE — ANATOMIA COMPLETA (RAIZ MAINFRAME)

Quando você acessa VSAM via COBOL (ou assembler por baixo), o retorno vem em dois níveis:

🧩 1. FILE STATUS (COBOL)

  • 2 bytes
  • Interface simplificada
  • Ex: 00, 10, 21, 23

👉 Isso é só a “versão resumida do erro”


🧠 2. VSAM STATUS (nível real — baixo nível)

Esse é o que você mostrou na imagem:

VSAM-CODE = 08 00 24

👉 Isso vem do REGISTER 15 + feedback interno do VSAM


🧠 ESTRUTURA DO VSAM CODE (3 CAMPOS)

CampoTamanhoOrigemFunção
Return Code1 byteRegister 15Status geral
Function Code1 byteVSAMTipo de operação
Feedback Code1 byteVSAMMotivo detalhado

👉 Total: 3 bytes


🧬 1. REGISTER (R15) — O CARA QUE MANDA

📌 O que é?

No IBM z/OS, o Register 15 (R15) é:

👉 O registrador padrão de retorno de programas


📦 Tamanho:

  • 32 bits (4 bytes) no hardware
  • Mas VSAM usa apenas 1 byte relevante (low-order)

📊 Uso:

  • Indica sucesso ou falha da macro VSAM (GET, PUT, etc.)

Valores típicos:

ValorSignificado
00Sucesso
04Warning
08Erro
12Erro severo

💥 Esse é o “OK/FAIL” da operação


⚙️ 2. FUNCTION CODE — O QUE O VSAM ESTAVA FAZENDO

📌 O que é?

Indica qual operação VSAM estava sendo executada


📦 Tamanho:

  • 1 byte

📊 Uso:

Ajuda a entender o contexto do erro

Exemplos:

CódigoOperação
00Acesso ao cluster base
04Acesso via AIX
08Inserção
0CUpdate
10Delete

💬 Pense como:
👉 “em que momento deu ruim?”


🚨 3. FEEDBACK FIELD CODE — O VERDADEIRO ERRO

📌 O que é?

👉 O coração do diagnóstico VSAM

Mostra exatamente por que falhou


📦 Tamanho:

  • 1 byte

📊 Uso:

Diagnóstico fino (nível sênior)

Exemplos famosos:

CódigoSignificado
00OK
04Duplicate key
08Record not found
0CEnd of dataset
10Length error
24Key out of range
28Sequence error

💥 Esse é o código que resolve incidente em produção


🧠 JUNTANDO TUDO

Exemplo:

VSAM-CODE = 08 00 24
CampoValorSignificado
R1508Erro
Function00Acesso cluster
Feedback24Key out of range

🔄 RELAÇÃO COM COBOL (FILE STATUS)

VSAM internoCOBOL FS
Feedback 0823
Feedback 2421
Feedback 0422

👉 COBOL simplifica — VSAM detalha


💡 RESUMO VISUAL


01 RETURN-STATUS. 05 FS-CODE PIC X(2). 05 VSAM-CODE. 10 VSAM-R15-RETURN PIC S9(4) Usage Comp-5. 10 VSAM-FUNCTION PIC S9(4) Usage Comp-5. 10 VSAM-FEEDBACK PIC S9(4) Usage Comp-5.

[ R15 ] [ FUNC ] [ FEEDBACK ]
↓ ↓ ↓
STATUS OPERAÇÃO CAUSA REAL

⚠️ IMPORTANTE (nível sênior)

👉 O COBOL esconde informação

Se você olha só:

FILE STATUS = 21

👉 Você está vendo só a superfície

💥 O diagnóstico real exige VSAM-CODE


INSIGHT FINAL (estilo Bellacosa)

  • R15 diz “deu erro”
  • Function diz “onde deu erro”
  • Feedback diz “por que deu erro”

🔥 PROVOCAÇÃO FINAL

Se você debuga VSAM só com FILE STATUS…

👉 você está dirigindo o mainframe olhando pelo retrovisor 😏

🎯 CONCLUSÃO (SOCO FINAL)

Se você não domina FILE STATUS…

👉 você não domina VSAM
👉 você não domina batch
👉 você não domina produção

💥 FILE STATUS é o log invisível do seu sistema

Ignore ele…
e o sistema vai te ensinar — da pior forma.


quarta-feira, 13 de novembro de 2019

O Caso do Return Code que Decidiu Quem Viveria no Batch

 

Bellacosa Maifnrame e o caso do return code que decidiu quem viveria no batch

☕ Um Café no Bellacosa Mainframe

O Caso do Return Code que Decidiu Quem Viveria no Batch

JCL IF/THEN/ELSE: o detetive invisível que interroga programas, examina falhas e escolhe o próximo passo

A chuva caía sobre o data center como uma sequência interminável de registros gravados em fita.

Do lado de fora, a cidade dormia. Dentro da sala de operações, milhares de luzes piscavam em silêncio, enquanto o z/OS processava folhas de pagamento, transferências bancárias, seguros, cartões de crédito, estoques, relatórios fiscais e uma quantidade de dinheiro que faria qualquer contador perder o sono.

Eram duas horas e dezessete da madrugada quando o telefone tocou.

— Bellacosa, temos um problema.

Do outro lado da linha, um jovem programador COBOL parecia nervoso.

— O relatório não foi enviado. O programa de geração terminou, mas o passo seguinte não executou. No spool aparece uma coisa chamada IF/THEN/ELSE. Acho que o JCL decidiu ignorar meu programa.

Acendi o abajur, empurrei para o lado uma velha revista de mistério dos anos 1950 e observei o copo de café frio sobre a mesa.

O rapaz ainda não sabia, mas havia acabado de encontrar uma das figuras mais discretas e poderosas do mundo batch.

O JCL não era apenas uma lista de programas.

Ele também podia tomar decisões.

E, em algum lugar daquele JOB, uma condição havia interrogado um Return Code, analisado as evidências e decidido que determinado passo não merecia executar.

O nome do suspeito?

IF / THEN / ELSE

Esta é a história de como o JCL aprendeu a escolher caminhos.


1. O JCL não é apenas um carregador de programas

Para um programador COBOL iniciante, o JCL costuma parecer uma espécie de porteiro do mainframe.

Ele informa:

  • qual programa será executado;

  • quais arquivos serão utilizados;

  • onde os relatórios serão gravados;

  • quais parâmetros serão enviados;

  • quais recursos o JOB precisará.

Um exemplo simples poderia ser:

//RELATOR  JOB (1234),'BELLACOSA',CLASS=A,MSGCLASS=X
//STEP01   EXEC PGM=GERAREL
//ENTRADA  DD DSN=EMPRESA.VENDAS.DIARIO,DISP=SHR
//SAIDA    DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*

Nesse caso, o JCL solicita ao sistema que execute o programa GERAREL.

Durante algum tempo, o iniciante imagina que o JCL faz apenas isso: chama programas e associa arquivos.

Mas existe um nível mais profundo.

Um JOB pode conter vários passos:

//STEP01 EXEC PGM=VALIDA
//STEP02 EXEC PGM=ATUALIZA
//STEP03 EXEC PGM=RELATOR
//STEP04 EXEC PGM=ENVIA

Agora surge uma pergunta crítica:

todos os passos devem executar mesmo quando um dos anteriores falhar?

Naturalmente, não.

Se o programa de validação descobrir que o arquivo de entrada está inválido, não faz sentido atualizar o banco de dados.

Se a atualização não for concluída, não é seguro gerar um relatório afirmando que tudo terminou corretamente.

Se o relatório não existir, não há motivo para tentar enviá-lo.

Foi para controlar decisões como essas que o JCL recebeu estruturas condicionais.


2. O que é IF/THEN/ELSE no JCL?

O IF/THEN/ELSE permite que o JOB escolha quais passos deverão executar com base no resultado de passos anteriores.

A ideia fundamental é a mesma encontrada no COBOL.

Em COBOL, podemos escrever:

IF WS-SALDO > 0
    DISPLAY 'CONTA POSITIVA'
ELSE
    DISPLAY 'CONTA SEM SALDO'
END-IF

O programa examina uma condição e escolhe uma ação.

No JCL, entretanto, a decisão é maior.

O JCL não escolhe apenas uma instrução.

Ele pode decidir se um programa inteiro será ou não executado.

Veja o exemplo básico:

//STEP01   EXEC PGM=PROGA
//TESTE01  IF (STEP01.RC = 0) THEN
//STEP02   EXEC PGM=PROGB
//         ELSE
//STEP03   EXEC PGM=PROGC
//         ENDIF

O fluxo é o seguinte:

  1. STEP01 executa o programa PROGA.

  2. O sistema registra o Return Code produzido por esse passo.

  3. O JCL avalia a condição STEP01.RC = 0.

  4. Se a condição for verdadeira, executa STEP02.

  5. Caso contrário, executa STEP03.

  6. Ao encontrar ENDIF, o fluxo condicional termina.

Visualmente:

                 STEP01
                   |
          STEP01.RC é igual a 0?
              /             \
           SIM               NÃO
            |                  |
         STEP02             STEP03
            \                  /
                 CONTINUA

É uma bifurcação na estrada do batch.

Um caminho será percorrido.

O outro ficará registrado no spool como um passo não executado por causa da lógica condicional.


3. O Return Code: a testemunha principal

O coração dessa história não é o IF.

É o Return Code.

O Return Code, geralmente abreviado como RC, é um valor devolvido por um programa ao terminar.

Ele comunica ao sistema o resultado da execução.

Uma convenção comum é:

Return CodeSignificado habitual
0Processamento concluído com sucesso
4Sucesso com advertência
8Erro de processamento
12Erro grave
16Falha severa

Mas existe uma regra fundamental:

O significado do Return Code pertence ao programa ou ao utilitário que o produziu.

Não existe uma lei universal determinando que RC=4 seja sempre aceitável ou que RC=8 represente exatamente o mesmo erro em todos os programas.

No IDCAMS, no DFSORT, em programas COBOL internos ou em produtos de terceiros, os significados podem variar.

Por isso, o programador deve conhecer o contrato de retorno do programa executado.

Imagine um programa de validação de clientes:

RC=0   Todos os registros são válidos
RC=4   Existem registros com advertências
RC=8   Existem registros rejeitados
RC=12  O arquivo não pôde ser processado

Nesse caso, talvez seja permitido continuar com RC=4.

A condição poderia ser:

//CHKVALID IF (STEP01.RC <= 4) THEN
//STEP02   EXEC PGM=ATUALIZA
//         ELSE
//STEPERRO EXEC PGM=TRATAERR
//         ENDIF

Agora o JOB aceita retorno zero ou quatro.

Isso demonstra por que o teste simplista RC = 0 nem sempre é suficiente.


4. Como um programa COBOL define o Return Code?

Em COBOL, o programa pode atribuir um valor ao registrador especial RETURN-CODE.

Exemplo:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. VALIDA01.

       DATA DIVISION.
       WORKING-STORAGE SECTION.

       01  WS-QTD-ERROS       PIC 9(05) VALUE ZERO.

       PROCEDURE DIVISION.

           PERFORM PROCESSAR-ARQUIVO

           IF WS-QTD-ERROS = ZERO
               MOVE 0 TO RETURN-CODE
           ELSE
               MOVE 8 TO RETURN-CODE
           END-IF

           GOBACK.

Quando o programa termina com:

MOVE 0 TO RETURN-CODE

o passo pode aparecer no spool com retorno zero.

Quando termina com:

MOVE 8 TO RETURN-CODE

o JCL poderá testar esse valor em um passo posterior.

Essa comunicação é extremamente importante.

O programa COBOL conhece o resultado funcional do processamento.

O JCL conhece o fluxo completo do JOB.

O Return Code é a ponte entre os dois.

É como se o programa deixasse um bilhete sobre a mesa:

“Terminei. Este é o estado do caso.”

O JCL lê o bilhete e decide o que fazer.


5. A anatomia correta de uma estrutura condicional

Observe este exemplo mais completo:

//FECHAMEN JOB (ACCT),'FECHAMENTO',CLASS=A,MSGCLASS=X
//*
//VALIDA   EXEC PGM=PGMVALID
//ARQENT   DD DSN=EMPRESA.MOVIMENTO.DIA,DISP=SHR
//RELERR   DD SYSOUT=*
//*
//IFVALID  IF (VALIDA.RC <= 4) THEN
//*
//ATUALIZA EXEC PGM=PGMATU
//ARQENT   DD DSN=EMPRESA.MOVIMENTO.DIA,DISP=SHR
//CADASTRO DD DSN=EMPRESA.CLIENTES.MASTER,DISP=OLD
//*
//IFATU    IF (ATUALIZA.RC = 0) THEN
//RELATOR  EXEC PGM=PGMREL
//SAIDA    DD SYSOUT=*
//         ELSE
//ERROATU  EXEC PGM=PGMERRO
//         ENDIF
//*
//         ELSE
//ERROVAL  EXEC PGM=PGMERRO
//         ENDIF

Temos dois níveis de decisão.

Primeiro:

IF (VALIDA.RC <= 4) THEN

Se a validação for aceitável, o JOB executa ATUALIZA.

Depois:

IF (ATUALIZA.RC = 0) THEN

Se a atualização terminar com sucesso, o relatório será gerado.

Caso contrário, ERROATU será executado.

Se a validação inicial falhar, o JOB nem chega à atualização. Ele segue diretamente para ERROVAL.

Esse é um exemplo de IF aninhado.

Funciona bem, mas exige disciplina.

Quanto mais níveis de aninhamento existirem, mais difícil será compreender o JOB.

Um JCL com sete ou oito IFs dentro de outros IFs pode se transformar em uma mansão noir cheia de corredores, portas falsas e quartos onde ninguém se lembra de ter entrado.


6. Operadores de comparação

O JCL permite comparar Return Codes de diferentes maneiras.

Igualdade

//TESTE IF (STEP01.RC = 0) THEN

Também pode ser encontrada a forma mnemônica:

//TESTE IF (STEP01.RC EQ 0) THEN

Diferente

//TESTE IF (STEP01.RC NE 0) THEN

Dependendo do ambiente e da codificação disponível, símbolos como ¬= podem aparecer, mas as formas mnemônicas são frequentemente mais claras e evitam problemas de caracteres.

Maior que

//TESTE IF (STEP01.RC GT 4) THEN

Menor que

//TESTE IF (STEP01.RC LT 8) THEN

Maior ou igual

//TESTE IF (STEP01.RC GE 8) THEN

Menor ou igual

//TESTE IF (STEP01.RC LE 4) THEN

As formas mnemônicas são:

OperadorSignificado
EQIgual
NEDiferente
GTMaior que
LTMenor que
GEMaior ou igual
LEMenor ou igual

7. Condições compostas com AND e OR

O JCL pode analisar mais de uma evidência.

Utilizando AND

//TESTE IF (STEP01.RC = 0 & STEP02.RC = 0) THEN

Ou, conforme a forma adotada:

//TESTE IF (STEP01.RC EQ 0 AND STEP02.RC EQ 0) THEN

A condição será verdadeira somente se os dois passos terminarem com retorno zero.

Exemplo prático:

  • STEP01 valida o arquivo de clientes;

  • STEP02 valida o arquivo de contratos;

  • STEP03 executa apenas quando os dois arquivos são válidos.

//IFOK     IF (STEP01.RC EQ 0 AND STEP02.RC EQ 0) THEN
//STEP03   EXEC PGM=ATUALIZA
//         ENDIF

Utilizando OR

//IFERRO   IF (STEP01.RC GE 8 OR STEP02.RC GE 8) THEN
//TRATAERR EXEC PGM=ERROGER
//         ENDIF

Aqui, o tratamento será executado se qualquer um dos passos retornar oito ou mais.

A importância dos parênteses

Em condições complexas, use parênteses para deixar a intenção visível:

//TESTE IF ((STEP01.RC LE 4) AND
//          (STEP02.RC EQ 0)) THEN

O JOB não é lugar para jogos de adivinhação.

Um programador pode compreender uma expressão hoje e esquecê-la seis meses depois. Um colega chamado às três da madrugada terá ainda menos paciência.

Escreva para a manutenção, não apenas para o interpretador.


8. RC não é a mesma coisa que ABEND

Essa é uma das distinções mais importantes para um iniciante.

Um Return Code significa que o programa chegou a uma conclusão normal e devolveu um resultado.

Um ABEND significa que ocorreu uma terminação anormal.

Exemplos de ABEND:

S0C7
S0C4
S806
U4038

Um S0C7, por exemplo, frequentemente está relacionado a uma operação numérica inválida, como tentar tratar conteúdo não numérico como número.

Um S806 pode indicar que o programa não foi encontrado em uma biblioteca de carga acessível.

Nesses casos, não estamos simplesmente diante de um RC=8.

O programa sofreu uma interrupção anormal.

O JCL permite testar situações de ABEND.

Exemplo:

//STEP01   EXEC PGM=PROGA
//IFABEND  IF (STEP01.ABEND) THEN
//DUMP     EXEC PGM=GERADUMP
//         ENDIF

Também é possível testar se um passo executou normalmente:

//IFNORMAL IF (STEP01.RUN AND NOT STEP01.ABEND) THEN
//STEP02   EXEC PGM=PROGB
//         ENDIF

A disponibilidade e a forma exata dos testes devem ser verificadas de acordo com os padrões do ambiente e a documentação utilizada pela instalação, mas o conceito central permanece:

  • RC trata o resultado de uma conclusão normal;

  • ABEND trata uma terminação anormal;

  • um passo pode não executar por causa de uma condição anterior;

  • um passo não executado não deve ser confundido com um programa que executou e retornou erro.

No spool, essas diferenças contam a história real do JOB.


9. O que acontece quando não existe ELSE?

O ELSE é opcional.

Podemos escrever:

//STEP01   EXEC PGM=PROGA
//SEOK     IF (STEP01.RC EQ 0) THEN
//STEP02   EXEC PGM=PROGB
//         ENDIF

Se STEP01.RC for zero, STEP02 executará.

Caso contrário, o bloco será ignorado e o JOB continuará depois do ENDIF.

Isso é útil quando existe uma ação necessária apenas em uma situação específica.

Exemplo:

//AVISO IF (VALIDA.RC EQ 4) THEN
//EMAIL EXEC PGM=ENVIAAV
//      ENDIF

O e-mail será enviado somente quando houver advertências.


10. Vários passos dentro do THEN e do ELSE

Um erro comum é imaginar que cada bloco pode conter apenas um EXEC.

Na verdade, vários passos podem ser agrupados.

//STEP01   EXEC PGM=VALIDA
//FLUXOOK  IF (STEP01.RC LE 4) THEN
//STEP02   EXEC PGM=ATUALIZA
//STEP03   EXEC PGM=RELATOR
//STEP04   EXEC PGM=ENVIA
//         ELSE
//STEP90   EXEC PGM=LOGERRO
//STEP91   EXEC PGM=NOTIFICA
//         ENDIF

Se a validação for aceitável, três programas serão executados.

Se não for, dois programas de tratamento serão acionados.

Esse tipo de construção aparece com frequência em ambientes de produção.


11. Exemplo realista: fechamento de vendas

Considere o seguinte processo noturno:

  1. Receber arquivo de vendas.

  2. Validar estrutura.

  3. Atualizar banco de dados.

  4. Gerar relatório.

  5. Enviar relatório.

  6. Em caso de erro, registrar ocorrência e notificar o suporte.

O JCL poderia ser:

//VENDAS   JOB (FIN),'FECHAMENTO',CLASS=A,MSGCLASS=X
//*
//VALIDA   EXEC PGM=VALVEND
//ARQVEN   DD DSN=LOJA.VENDAS.DIARIA,DISP=SHR
//RELERR   DD SYSOUT=*
//*
//IFVAL    IF (VALIDA.RC LE 4) THEN
//*
//ATUALIZA EXEC PGM=ATUVEND
//ARQVEN   DD DSN=LOJA.VENDAS.DIARIA,DISP=SHR
//BASEVEN  DD DSN=LOJA.VENDAS.MASTER,DISP=OLD
//*
//IFATU    IF (ATUALIZA.RC EQ 0) THEN
//RELATOR  EXEC PGM=RELVEND
//RELATORI DD DSN=LOJA.RELATORIO.DIARIO,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(5,2)),
//            DCB=(RECFM=FB,LRECL=133,BLKSIZE=0)
//*
//ENVIA    EXEC PGM=MAILBAT
//ARQMAIL  DD DSN=LOJA.RELATORIO.DIARIO,DISP=SHR
//         ELSE
//LOGATU   EXEC PGM=LOGERRO
//AVISAATU EXEC PGM=AVISOPS
//         ENDIF
//*
//         ELSE
//LOGVAL   EXEC PGM=LOGERRO
//AVISAVAL EXEC PGM=AVISOPS
//         ENDIF

Agora examine a lógica.

Cenário 1: validação retorna zero

O arquivo está correto.

O JOB entra no primeiro THEN.

Cenário 2: validação retorna quatro

O arquivo contém advertências permitidas.

Como a condição é LE 4, o processamento continua.

Cenário 3: validação retorna oito

O JOB ignora atualização, relatório e envio.

Executa LOGVAL e AVISAVAL.

Cenário 4: atualização retorna oito

A validação foi aceita, mas a atualização falhou.

O relatório e o envio não executam.

O JOB chama LOGATU e AVISAATU.

Esse desenho impede que um relatório aparentemente correto seja enviado após uma atualização malsucedida.

É assim que uma estrutura condicional protege a integridade operacional.


12. IF/THEN/ELSE versus COND

Antes da popularização das estruturas condicionais explícitas, muitos JOBs utilizavam intensamente o parâmetro COND.

Exemplo:

//STEP02 EXEC PGM=PROGB,COND=(0,NE,STEP01)

O problema é que COND trabalha com uma lógica que muitos iniciantes consideram invertida.

O parâmetro indica uma condição para ignorar o passo.

Em outras palavras, quando a condição do COND é verdadeira, o passo não executa.

Isso exige atenção.

No exemplo:

COND=(0,NE,STEP01)

a interpretação é aproximadamente:

Ignore STEP02 se o Return Code de STEP01 for diferente de zero.

Portanto, STEP02 executa apenas quando STEP01.RC é zero.

O equivalente com IF é mais legível:

//TESTE IF (STEP01.RC EQ 0) THEN
//STEP02 EXEC PGM=PROGB
//      ENDIF

Compare:

COND=(0,NE,STEP01)

com:

IF (STEP01.RC EQ 0) THEN

A segunda forma parece uma frase.

Por isso, em fluxos complexos, o IF/THEN/ELSE geralmente facilita a leitura e a manutenção.

Isso não significa que COND esteja morto.

Muitos JOBs antigos e novos ainda o utilizam.

Um profissional de mainframe precisa compreender os dois.

Mas deve evitar misturar COND e estruturas IF sem necessidade, pois a combinação pode criar comportamentos difíceis de analisar.


13. Passo a passo para investigar um JOB condicional

Quando você encontrar um JCL grande, não tente compreender tudo ao mesmo tempo.

Use o método Bellacosa de investigação batch.

Passo 1 — Localize todos os EXEC

Anote cada step:

VALIDA
ATUALIZA
RELATOR
ENVIA
LOGERRO
AVISOPS

Isso revela os atores da história.

Passo 2 — Localize todos os IF

Procure:

IF
ELSE
ENDIF

Marque o início e o fim de cada bloco.

Passo 3 — Descubra qual step está sendo testado

Exemplo:

IF (VALIDA.RC LE 4) THEN

O suspeito interrogado é VALIDA.

Passo 4 — Consulte o significado dos Return Codes

Descubra o contrato do programa.

Talvez:

0 = sucesso
4 = aviso
8 = arquivo inválido
12 = falha de abertura

Sem essa informação, a condição é apenas um número sem contexto.

Passo 5 — Desenhe o fluxo

Use papel, quadro ou editor de texto:

VALIDA
  |
RC <= 4?
 /      \
SIM      NÃO
 |        |
ATUALIZA  LOGERRO
 |
RC = 0?
 /      \
SIM      NÃO
 |        |
RELATOR  AVISOPS
ENVIA

Passo 6 — Compare com o spool

Verifique:

  • quais passos realmente executaram;

  • quais foram ignorados;

  • quais retornaram código;

  • se houve ABEND;

  • qual foi o maior Return Code do JOB;

  • se alguma condição alterou o fluxo.

O spool é a cena do crime.

Não confie apenas no que o desenvolvedor acredita que aconteceu.

Leia as evidências.


14. Erros comuns de iniciantes

Considerar qualquer valor diferente de zero como desastre

Nem sempre RC=4 representa falha.

Pode ser apenas uma advertência.

O contrato do programa deve definir isso.

Testar o step errado

IF (STEP02.RC EQ 0) THEN

não funciona como esperado se STEP02 não executou ou se a intenção era testar STEP01.

Nomes claros reduzem esse risco.

Esquecer o ENDIF

Cada estrutura precisa ser encerrada corretamente.

Em fluxos aninhados, identação e comentários ajudam muito.

Criar condições excessivamente complexas

Uma expressão com muitos AND, OR, NOT e parênteses pode funcionar, mas se tornar impossível de manter.

Às vezes, dividir o processamento em mais de um bloco é melhor.

Confundir step ignorado com erro

Um passo dentro de um ramo não escolhido pode aparecer como não executado.

Isso não significa que seu programa falhou.

Significa que o JCL decidiu não chamá-lo.

Tratar ABEND como Return Code comum

Um S0C7 não é simplesmente RC=7.

ABENDs possuem outra natureza e exigem tratamento apropriado.

Não documentar Return Codes funcionais

Um programa COBOL que retorna RC=6, RC=20 ou RC=32 sem documentação está deixando uma bomba-relógio para a equipe de produção.


15. Boas práticas para JCL de produção

Use nomes significativos

Evite:

//STEP1
//STEP2
//STEP3

Prefira:

//VALIDA
//ATUALIZA
//GERAREL
//ENVIA

O nome do step deve ajudar a contar a história do JOB.

Nomeie os blocos condicionais

//IFVALID IF (VALIDA.RC LE 4) THEN

Isso facilita localizar mensagens e interpretar o fluxo.

Comente decisões incomuns

//* RC=4 INDICA REGISTROS REJEITADOS, MAS PROCESSAMENTO PODE CONTINUAR

Um bom comentário economiza horas de investigação.

Padronize Return Codes

A equipe deve saber o que cada faixa representa.

Por exemplo:

0      Sucesso
4      Advertência
8      Erro funcional
12     Erro técnico
16+    Falha severa

Evite aninhamento profundo

Se o JOB parecer uma boneca russa de IFs, talvez seja hora de redesenhar o fluxo.

Sempre pense no tratamento de erro

Não basta impedir a execução de passos posteriores.

Pergunte:

  • quem será notificado?

  • onde o erro será registrado?

  • o arquivo será preservado?

  • será necessário restart?

  • o operador saberá qual ação tomar?

  • o scheduler interpretará o resultado corretamente?

Um bom IF não apenas impede problemas.

Ele orienta a recuperação.


16. Curiosidades do mundo batch

O JOB pode terminar “bem”, mas o negócio ter falhado

Tecnicamente, um programa pode terminar com RC=0 mesmo quando não processou nada útil.

Por exemplo, o arquivo estava vazio, mas o programa considerou isso normal.

O sistema operacional vê sucesso.

O negócio talvez veja um desastre.

Por isso, Return Codes devem representar estados relevantes para a operação.

O maior RC costuma chamar atenção

Ferramentas de operação e schedulers frequentemente analisam o maior Return Code encontrado no JOB.

Mas o comportamento exato depende das regras da instalação e da automação utilizada.

Schedulers também tomam decisões

Produtos como IBM Workload Scheduler, Control-M e outras soluções podem avaliar status de JOBs, Return Codes, dependências, horários e recursos.

Nesse cenário, existe uma cadeia de inteligência:

Programa COBOL
      ↓
Return Code
      ↓
JCL IF/THEN/ELSE
      ↓
Resultado do JOB
      ↓
Scheduler
      ↓
Próximo processamento

Um pequeno número devolvido por um programa pode impedir a execução de uma cadeia inteira de processamento corporativo.

Um RC mal definido pode custar caro

Imagine um programa que detecta inconsistência financeira, grava uma mensagem no relatório, mas termina com RC=0.

O JCL entende que tudo ocorreu corretamente.

O relatório é enviado.

O scheduler libera os próximos JOBs.

Horas depois, alguém descobre que os dados estavam errados.

O problema não foi apenas técnico.

Foi uma falha de comunicação entre programa e operação.


17. O exemplo definitivo para um Padawan COBOL

Vamos construir um fluxo simples e completo.

O objetivo é:

  1. validar um arquivo;

  2. processá-lo se estiver correto;

  3. gerar relatório se o processamento terminar bem;

  4. executar tratamento se algo falhar.

//PEDIDOS  JOB (1234),'PEDIDOS',CLASS=A,MSGCLASS=X
//*
//VALIDA   EXEC PGM=VALPED
//ARQPED   DD DSN=EMPRESA.PEDIDOS.ENTRADA,DISP=SHR
//SYSOUT   DD SYSOUT=*
//*
//IFVAL    IF (VALIDA.RC LE 4) THEN
//*
//PROCESSA EXEC PGM=PROCPED
//ARQPED   DD DSN=EMPRESA.PEDIDOS.ENTRADA,DISP=SHR
//CADPED   DD DSN=EMPRESA.PEDIDOS.MASTER,DISP=OLD
//SYSOUT   DD SYSOUT=*
//*
//IFPROC   IF (PROCESSA.RC EQ 0) THEN
//RELATOR  EXEC PGM=RELPED
//RELATORI DD SYSOUT=*
//         ELSE
//ERROPROC EXEC PGM=TRATPED
//MOTIVO   DD *
FALHA NO PROCESSAMENTO DE PEDIDOS
/*
//         ENDIF
//*
//         ELSE
//ERROVAL  EXEC PGM=TRATPED
//MOTIVO   DD *
ARQUIVO DE PEDIDOS REPROVADO NA VALIDACAO
/*
//         ENDIF

O raciocínio é:

VALIDA
  |
  +-- RC 0 ou 4?
        |
        +-- SIM → PROCESSA
        |            |
        |            +-- RC 0?
        |                  |
        |                  +-- SIM → RELATOR
        |                  |
        |                  +-- NÃO → ERROPROC
        |
        +-- NÃO → ERROVAL

O iniciante que aprende a desenhar esse fluxo já está deixando de apenas “ler JCL”.

Ele começa a pensar como alguém de produção.


18. O easter egg do velho operador

Dizem que, em um data center antigo, havia um operador chamado Moretti.

Ninguém sabia sua idade. Alguns juravam que ele já trabalhava ali quando os discos ainda pareciam máquinas de lavar.

Moretti tinha um ritual.

Sempre que um JOB terminava, ele não olhava primeiro para o programa, para o consumo de CPU ou para o horário.

Ele procurava o Return Code.

Certa madrugada, um novato perguntou:

— Por que o senhor olha primeiro para um número tão pequeno?

Moretti respondeu:

— Porque os programas falam muito nos relatórios, mas dizem a verdade no retorno.

Anos depois, quando Moretti se aposentou, encontraram um cartão perfurado em sua gaveta.

Nele havia apenas uma frase:

RC=0 NÃO SIGNIFICA QUE O UNIVERSO ESTÁ CORRETO.
SIGNIFICA APENAS QUE O PROGRAMA DISSE QUE ESTÁ.

Ninguém sabe se a história é verdadeira.

Mas todo programador mainframe deveria guardar a frase.


19. A conclusão do caso

Naquela madrugada, o jovem programador voltou ao telefone.

— Bellacosa, encontrei o problema. O primeiro programa terminou com RC=4. O IF estava testando apenas RC=0. Por isso o passo de envio não executou.

— E o que significa RC=4 nesse programa?

Houve silêncio.

Depois, ouvi o som de páginas sendo folheadas.

— Significa que o relatório foi gerado, mas alguns registros foram ignorados. Ainda é permitido enviá-lo.

— Então o erro não estava no programa.

— Estava na condição.

Exatamente.

O programa havia feito seu trabalho.

O JCL também.

O problema era que alguém havia escrito uma regra incompleta.

A condição dizia:

IF (STEP01.RC EQ 0) THEN

Mas a regra de negócio deveria aceitar zero e quatro:

IF (STEP01.RC LE 4) THEN

Uma pequena diferença.

Dois caracteres.

Uma decisão completamente diferente.

No mainframe, muitas catástrofes não começam com explosões, fumaça ou mensagens dramáticas.

Elas começam com detalhes.

Um dataset com o DISP errado.

Um campo numérico mal inicializado.

Uma biblioteca ausente no STEPLIB.

Um Return Code não documentado.

Ou um IF que pergunta a coisa errada.

O IF/THEN/ELSE transforma o JCL em algo muito maior do que uma sequência estática de comandos. Ele permite que o JOB observe resultados, escolha caminhos, evite processamentos inúteis, proteja dados, acione tratamentos e automatize decisões operacionais.

Para quem trabalha com COBOL, produção, suporte, operações ou sistemas, dominar esse recurso não é opcional.

É parte da alfabetização batch.

Quando você compreender o Return Code, começará a entender o programa.

Quando compreender o IF, começará a entender o JOB.

E quando conseguir seguir o fluxo inteiro pelo spool, examinando cada passo, cada retorno, cada desvio e cada programa ignorado...

Bem...

Nesse momento, jovem Padawan, você já não estará apenas executando JCL.

Estará investigando o mainframe.

E em uma madrugada chuvosa, quando um JOB de milhões de reais parar sem explicação aparente, talvez alguém ligue para você.

Na tela, uma única linha estará esperando:

//MISTERIO IF (STEP01.RC GT 4) THEN

O café estará frio.

A sala estará escura.

E o caso será seu.

domingo, 22 de junho de 2014

☕🔥 MAXCC — O “HUMOR” DO JOB NO z/OS

 

Bellacosa Mainframe e o max-cc conditional code

☕🔥 MAXCC — O “HUMOR” DO JOB NO z/OS

Quando o Mainframe Diz:

“SEU JOB TERMINOU… MAS EU TENHO ALGO A DIZER.”

Se existe uma coisa que TODO Junior Padawan COBOL precisa aprender cedo…

é que no z/OS:

nem todo fim de job é igual.

Às vezes o JOB termina:

✅ normalmente
⚠️ com avisos
🔥 com erros graves
☠️ completamente destruído

E quem conta essa história é o:

🚨 MAXCC


☕ O QUE É MAXCC?

MAXCC significa:

MAXIMUM CONDITION CODE

É o maior retorno gerado pelos steps do JOB.


🔥 A FILOSOFIA DO MAXCC

No z/OS:

programas “conversam” com o scheduler usando códigos numéricos.

Exemplo:

RETURN-CODE = 0

significa:

“Tudo OK.”

Mas:

RETURN-CODE = 16

significa:

“O APOCALIPSE CHEGOU.”


☕ O MAXCC MAIS FAMOSO

No SDSF/JESMSGLG:

MAXCC=0000

ou:

COND CODE 0004

🔥 O SEGREDO

MAXCC NÃO É ABEND.

Isso é MUITO importante.


☕ ABEND

Falha anormal.

Exemplo:

  • S0C7

  • S0C4

  • S806


☕ MAXCC

Programa terminou normalmente…

MAS quer avisar algo.


🔥 MAXCC 00 — O “MUNDO EM PAZ”

✅ MAXCC=0000

Significa:

tudo terminou perfeitamente.


☕ EXEMPLO

IEF142I STEP01 - STEP WAS EXECUTED - COND CODE 0000

🔥 INTERPRETAÇÃO BELLACOSA

O mainframe está dizendo:

☕ “Excelente, Padawan. Nada explodiu hoje.”


☕ CENÁRIO TÍPICO

  • arquivo processado

  • SORT OK

  • DB2 OK

  • nenhum warning

  • tudo consistente


🔥 MAXCC 04 — O “WARNING ELEGANTE”

⚠️ MAXCC=0004

O JOB terminou.

Mas:

algo merece atenção.


☕ O MAIS IMPORTANTE

MAXCC 4 normalmente NÃO é erro fatal.

Muitos jobs em produção aceitam:

RC=4 normalmente.


🔥 EXEMPLOS CLÁSSICOS


☕ SORT

SORT FIELDS=COPY

Mas:

  • registro inválido ignorado

  • campo truncado

  • duplicidade encontrada

Resultado:

RC=4


☕ IDCAMS

DELETE DATASET

Dataset não existe.

IDCAMS retorna:

4

Porque:

“não achei, mas sobrevivi.”


☕ IEBCOPY

Membro duplicado.

Warning.

RC=4.


🔥 INTERPRETAÇÃO BELLACOSA

☕ “Nada morreu… mas eu notei uma coisa estranha.”


🔥 MAXCC 08 — O “ERRO OPERACIONAL”

❌ MAXCC=0008

Agora a conversa ficou séria.


☕ SIGNIFICADO

o processamento falhou parcialmente.


🔥 MUITOS JOBS PARAM EM RC=8

Schedulers frequentemente tratam:

RC >= 8

como falha.


☕ EXEMPLOS CLÁSSICOS


☕ SORT

Campo inválido.

Chave inconsistente.

Arquivo problemático.


☕ IDCAMS

Falha em DEFINE CLUSTER.


☕ DB2

SQLCODE sério.


☕ COBOL

Programa detecta erro de negócio:

MOVE 8 TO RETURN-CODE
STOP RUN

🔥 INTERPRETAÇÃO BELLACOSA

☕ “Padawan… algo deu errado e você PRECISA olhar.”


🔥 MAXCC 12 — O “DESASTRE CONTROLADO”

☠️ MAXCC=0012

Agora entramos na zona crítica.


☕ SIGNIFICADO

Erro grave.

Processamento comprometido.


🔥 EXEMPLOS CLÁSSICOS

  • falha forte em SORT

  • utility quebrada

  • VSAM inconsistente

  • falha DB2 importante

  • step inutilizado


☕ O JOB AINDA TERMINOU

Isso diferencia de ABEND.

O programa conseguiu:

terminar conscientemente.

Mas avisando:

“o resultado NÃO é confiável.”


🔥 EXEMPLO COBOL

IF WS-ERRO-CRITICO = 'S'
   MOVE 12 TO RETURN-CODE
   STOP RUN
END-IF

🔥 INTERPRETAÇÃO BELLACOSA

☕ “O castelo ainda está de pé… mas está pegando fogo.”


🔥 MAXCC 16 — O “JUÍZO FINAL”

🚨 MAXCC=0016

Aqui o sistema está praticamente gritando.


☕ SIGNIFICADO

falha gravíssima.


🔥 MUITOS PRODUTOS TRATAM 16 COMO FATAL

Especialmente:

  • DFSORT

  • IDCAMS

  • DB2 utilities

  • IEBCOPY

  • custom utilities


☕ EXEMPLOS CLÁSSICOS

  • arquivo inacessível

  • utility impossível de executar

  • parâmetro inválido

  • corrupção

  • inconsistência crítica


🔥 COBOL TAMBÉM PODE RETORNAR 16

MOVE 16 TO RETURN-CODE
STOP RUN

☕ INTERPRETAÇÃO BELLACOSA

☕ “Padawan… o processamento fracassou de forma épica.”


🔥 O SEGREDO MAIS IMPORTANTE

CADA PRODUTO INTERPRETA RC DE FORMA DIFERENTE.


☕ EXEMPLO

Para um utilitário:

RC=4

pode ser trivial.

Para outro:

RC=4

já significa problema sério.


🔥 O JCL E O COND=

Agora nasce o verdadeiro conhecimento Jedi.


☕ EXEMPLO

//STEP2 EXEC PGM=PROG2,COND=(8,LT)

Significa:

execute STEP2 somente se RC anterior NÃO for menor que 8.


🔥 O IF/THEN/ELSE MODERNO

Mais elegante:

// IF (STEP1.RC > 4) THEN
//STEPERR EXEC PGM=ALERTA
// ENDIF

☕ O MAXCC E O JES2

O JES acompanha:

  • RCs

  • ABENDs

  • steps

  • histórico do JOB


🔥 O MAXCC E O SCHEDULER

Ferramentas como:

  • Control-M

  • CA7

  • TWS

tomam decisões usando:

RC/MAXCC.


☕ EXEMPLO REAL

RC=0 → continua fluxo
RC=4 → warning
RC>=8 → dispara incidente

🔥 O MAIOR ERRO DO PADAWAN

Achar:

RC=4 = tudo OK

Não necessariamente.

Você PRECISA entender:

o contexto do utilitário/programa.


☕ O SEGREDO DOS VETERANOS

Veteranos sempre perguntam:

“QUEM RETORNOU O RC?”

Porque:

  • DFSORT

  • IDCAMS

  • COBOL

  • DB2

  • CICS utilities

cada um possui semântica própria.


🔥 CURIOSIDADE HISTÓRICA

MAXCC existe desde os tempos do:

OS/360

Década de:

🏛️ 1960

IBM precisava que jobs batch “conversassem” automaticamente entre si.

Então nasceram:

  • return codes

  • condition codes

  • job control logic


☕ EASTER EGG MAINFRAME

Veteranos brincam:

RC=0 → “milagre corporativo”

RC=4 → “o sistema tossiu”

RC=8 → “alguém vai abrir chamado”

RC=12 → “gerência foi avisada”

RC=16 → “prepare o café… a madrugada será longa.”


domingo, 25 de fevereiro de 2007

O que é o comando STOP RUN em COBOL?

  

Bellacosa Mainframe e o comando Stop Run em Cobol

O que é o comando STOP RUN em COBOL?

O comando STOP RUN é uma das instruções mais conhecidas da linguagem COBOL.

Sua função é:

Encerrar a execução do programa

Quando o COBOL encontra um STOP RUN, ele finaliza o programa e devolve o controle ao sistema operacional (z/OS), ao CICS, ao Job Batch ou ao ambiente que executou o programa.


Sintaxe

STOP RUN.

Exemplo Simples

IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.

PROCEDURE DIVISION.

DISPLAY 'OLA MUNDO'.

STOP RUN.

Resultado:

OLA MUNDO

O programa termina logo após o DISPLAY.


Fluxo de Execução

Início Programa
       ↓
Comandos COBOL
       ↓
STOP RUN
       ↓
Fim Programa
       ↓
Retorno ao z/OS

O que acontece internamente?

Quando executado:

STOP RUN.

o COBOL:

✅ Fecha arquivos abertos

✅ Libera memória

✅ Finaliza o Language Environment (LE)

✅ Retorna ao sistema operacional

✅ Define o Return Code


Exemplo em Batch

DISPLAY 'PROCESSAMENTO OK'.

STOP RUN.

JCL:

//STEP1 EXEC PGM=FIN001

Resultado:

CC 0000

(Job encerrado com sucesso)


STOP RUN e Return Code

Podemos definir um código de retorno.

Exemplo:

MOVE 8 TO RETURN-CODE.

STOP RUN.

Resultado:

CC 0008

No SDSF:

RC=0008

Exemplo de Erro

IF SQLCODE NOT = 0

   MOVE 16 TO RETURN-CODE

   STOP RUN

END-IF.

Resultado:

CC=0016

STOP RUN x GOBACK

Uma das dúvidas mais comuns.


STOP RUN

Finaliza completamente a aplicação.

STOP RUN.

GOBACK

Retorna ao programa chamador.

GOBACK.

Exemplo

Programa principal:

CALL 'SUBROT1'.

Subprograma:

GOBACK.

Retorna ao programa principal.


Se usar:

STOP RUN.

todo o processo termina.


Exemplo Visual

Com GOBACK

MAIN
 ↓
SUB1
 ↓
GOBACK
 ↓
MAIN continua

Com STOP RUN

MAIN
 ↓
SUB1
 ↓
STOP RUN
 ↓
Tudo termina

Uso em Subprogramas

Normalmente:

❌ Evita-se STOP RUN

✅ Usa-se GOBACK


Exemplo Incorreto

PROGRAM-ID. SUBROT1.

DISPLAY 'SUB'.

STOP RUN.

Se chamado por:

CALL 'SUBROT1'

todo o JOB poderá terminar.


Exemplo Correto

PROGRAM-ID. SUBROT1.

DISPLAY 'SUB'.

GOBACK.

STOP RUN em CICS

Programas CICS não devem usar:

STOP RUN

Normalmente utilizam:

EXEC CICS RETURN
END-EXEC

STOP RUN em IMS

Em IMS TM também não é recomendado.

Utilizam-se comandos específicos do ambiente.


STOP RUN em Batch

É onde aparece com maior frequência.


Exemplo:

OPEN INPUT ARQENT.

PERFORM PROCESSA-ARQUIVO.

CLOSE ARQENT.

STOP RUN.

STOP RUN e Arquivos

Antes do STOP RUN é boa prática:

CLOSE ARQENT.
CLOSE ARQSAI.

STOP RUN.

Embora...

O runtime normalmente feche os arquivos automaticamente.


STOP RUN e Language Environment

O LE (Language Environment) interpreta:

STOP RUN

como:

Fim da aplicação

Executando rotinas de limpeza.


Evolução Histórica

Nas versões antigas:

STOP RUN

era praticamente obrigatório.

Hoje:

GOBACK

é mais utilizado em muitos ambientes.


Boas Práticas

✅ Use STOP RUN em programas principais Batch

✅ Use GOBACK em subprogramas

✅ Defina RETURN-CODE quando necessário

✅ Feche arquivos antes de terminar


Erros Comuns

Usar STOP RUN em subprograma

Pode encerrar toda a aplicação.


Usar STOP RUN em CICS

Pode gerar problemas de execução.


Não definir RETURN-CODE

Dificulta automação e controle do Scheduler.


Exemplo Completo

IDENTIFICATION DIVISION.
PROGRAM-ID. TESTE.

DATA DIVISION.

WORKING-STORAGE SECTION.

01 WS-TOTAL PIC 9(5).

PROCEDURE DIVISION.

MOVE 100 TO WS-TOTAL.

DISPLAY 'TOTAL = ' WS-TOTAL.

MOVE 0 TO RETURN-CODE.

STOP RUN.

Curiosidades

1. STOP RUN existe desde as primeiras versões do COBOL

2. É um dos comandos mais executados do mundo corporativo

3. Milhões de JOBs Batch terminam diariamente através dele

4. Em aplicações modernas, GOBACK costuma substituir STOP RUN em muitos cenários


Resumo Rápido

ComandoFunção
STOP RUNFinaliza o programa
GOBACKRetorna ao chamador
RETURN-CODEDefine código de retorno
CLOSEFecha arquivos
EXEC CICS RETURNFinaliza transação CICS
BatchUso comum de STOP RUN
SubprogramaPreferir GOBACK

Conclusão

O STOP RUN é o comando responsável por encerrar a execução de um programa COBOL e devolver o controle ao ambiente que o executou. Em programas Batch ele é amplamente utilizado, enquanto em subprogramas normalmente é substituído por GOBACK, que retorna o controle ao programa chamador sem finalizar toda a aplicação.

Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...