☕ 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 COMP-3. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta COMP-3. Mostrar todas as mensagens

quarta-feira, 10 de junho de 2026

☕💣🚀 COMP-1, COMP-2, COMP-3, COMP-4 e COMP-5 para o Programador COBOL Jr.

 

Bellacosa Mainframe e as variaveis computacionais do COBOL 

☕💣🚀 COMP-1, COMP-2, COMP-3, COMP-4 e COMP-5 para o Programador COBOL Jr.

Uma das maiores fontes de confusão para quem começa em COBOL é entender por que existem tantos tipos numéricos.

A resposta está na história dos mainframes IBM.

Cada COMP surgiu para resolver um problema específico de armazenamento, desempenho ou precisão matemática. (IBM)


Linha do Tempo

TipoSurgiu
COMPDécada de 1960
COMP-1Década de 1970
COMP-2Década de 1970
COMP-3Década de 1960
COMP-4Década de 1970
COMP-5Década de 1980

Os números exatos variam conforme compilador e plataforma, mas COMP-3 e COMP já existiam nos ambientes System/360. COMP-1, COMP-2 e COMP-4 apareceram como extensões IBM. COMP-5 surgiu posteriormente para resolver limitações do BINARY tradicional. (IBM)


Bellacosa Mainframe apresenta as variavis numericas do cobol comp

COMP-1

O que é

Ponto flutuante simples (single precision).

Ocupa:

  • 4 bytes

Utilizado para:

  • cálculos científicos

  • engenharia

  • estatística

Não deve ser usado para dinheiro. (IBM)


Exemplo

01 WS-TEMPERATURA COMP-1.

MOVE 23.75 TO WS-TEMPERATURA.

Vantagens

  • rápido

  • suporta expoentes

  • ocupa pouco espaço


Desvantagens

  • perde precisão decimal

  • gera arredondamentos inesperados


Exemplo clássico

COMPUTE RESULT = 0.1 + 0.2

Resultado pode não ser exatamente:

0.300000

Isso acontece porque o valor é armazenado em binário.


COMP-2

O que é

Ponto flutuante duplo (double precision).

Ocupa:

  • 8 bytes

Muito mais preciso que COMP-1. (IBM)


Exemplo

01 WS-PI COMP-2.

MOVE 3.14159265358979 TO WS-PI.

Vantagens

  • enorme faixa de valores

  • excelente precisão científica


Desvantagens

  • mais lento

  • ocupa mais memória

  • inadequado para dinheiro


COMP-3

O Rei dos Bancos

Também chamado:

PACKED DECIMAL

ou

COMPUTATIONAL-3

É o formato mais amado pelos bancos. (IBM)


Como funciona

Cada byte armazena:

2 dígitos

mais um nibble de sinal.


Exemplo

01 SALDO PIC S9(7)V99 COMP-3.

Valor:

12345.67

Internamente:

12 34 56 7C

(C = positivo)


Vantagens

  • extremamente compacto

  • precisão decimal perfeita

  • ideal para dinheiro


Desvantagens

  • CPU precisa converter para cálculo

  • não é legível em dump


Melhor uso

Contas correntes
Faturas
Cartões
Seguros
Folha de pagamento

COMP-4

O que é

Binário IBM.

Sinônimo de:

BINARY
COMP

na maioria dos compiladores IBM. (IBM)


Exemplo

01 CONTADOR PIC S9(4) COMP-4.

Tamanho

DígitosBytes
1-42
5-94
10-188

(IBM)


Vantagens

  • muito rápido

  • ideal para índices

  • excelente para contadores


Desvantagens

O comportamento depende do:

TRUNC(STD)
TRUNC(OPT)
TRUNC(BIN)

Isso já causou milhares de bugs em migrações COBOL. (IBM)


COMP-5

O que é

Binary Native.

Foi criado para eliminar limitações do COMP-4. (IBM)


Exemplo

01 WS-ID PIC S9(4) COMP-5.

Diferença Fundamental

Mesmo declarando:

PIC S9(4)

um COMP-5 de 2 bytes pode armazenar:

-32768
até
+32767

porque usa a capacidade real do campo binário. (IBM)


Vantagens

  • mais rápido

  • ideal para APIs

  • ideal para CICS

  • ideal para LE

  • ideal para interoperabilidade com C


Desvantagens

  • pode surpreender quem espera validação pelo PIC

  • programas antigos podem comportar-se diferente


Comparação Geral

CaracterísticaCOMP-1COMP-2COMP-3COMP-4COMP-5
TipoFloatFloatDecimalBinárioBinário Nativo
Bytes48Variável2/4/82/4/8
Dinheiro❌❌✅⚠️⚠️
VelocidadeAltaAltaMédiaMuito AltaMuito Alta
Precisão DecimalBaixaMédiaExcelenteBoaBoa
InteroperabilidadeMédiaMédiaBaixaMédiaExcelente

Opções de Compilação que Afetam Tudo

TRUNC

TRUNC(STD)
TRUNC(OPT)
TRUNC(BIN)

Principal responsável por diferenças em COMP e COMP-4. (IBM)


ARITH

ARITH(COMPAT)
ARITH(EXTEND)

Impacta precisão matemática.

Muito importante para:

COMP-3
COMPUTE
DIVIDE
MULTIPLY

NUMPROC

NUMPROC(PFD)
NUMPROC(MIG)
NUMPROC(NOPFD)

Afeta tratamento de sinais inválidos em COMP-3.


RULES(NOEVENPACK)

Detecta packed decimals com número par de dígitos, ajudando a otimizar COMP-3. (IBM)


Problemas Conhecidos

1. Dinheiro em COMP-1

Erro clássico.

01 SALDO COMP-1.

Nunca faça isso.


2. Migração COBOL V4 → V6

Mudanças em:

TRUNC
ARITH
OPTIMIZATION

geraram diferenças de resultados em milhares de aplicações. (IBM)


3. COMP-3 Corrompido

Dump:

12 34 5F

Sinal inválido.

Pode gerar:

S0C7

4. Overflow Silencioso

Muito comum em:

COMP
COMP-4

quando TRUNC(BIN) está ativo.


Easter Eggs e Curiosidades

1. O banco não gosta de FLOAT

Em muitos bancos você encontrará:

0 ocorrências de COMP-1
0 ocorrências de COMP-2

em milhões de linhas COBOL.


2. COMP-3 domina Wall Street

Grande parte dos sistemas financeiros de alto volume ainda utiliza COMP-3 para valores monetários devido à precisão decimal exata.


3. TRUNC(BIN) "transforma" COMP em COMP-5

Na prática, muitos comportamentos tornam-se equivalentes para operações binárias. (IBM)


4. Packed Decimal foi uma genialidade da IBM

Quando memória custava fortunas, armazenar dois dígitos por byte era uma enorme vantagem econômica.


Regra de Ouro para o Programador COBOL Jr.

Se estiver em dúvida:

Dinheiro      -> COMP-3
Contadores    -> COMP-5
Índices       -> COMP-5
Percentuais   -> COMP-3
Cálculos científicos -> COMP-2
Integração C/C++ -> COMP-5

Em ambientes modernos z/OS com Enterprise COBOL 6.x, a combinação mais comum e segura é:

COMP-3 para valores financeiros
COMP-5 para inteiros e contadores

Essa dupla cobre praticamente 95% das necessidades de aplicações corporativas em bancos, seguradoras e grandes empresas. (IBM)

☕ Um Café no Bellacosa Mainframe

Viagem ao Fundo do Mar dos Formatos Numéricos COBOL

Uma expedição pelas profundezas de COMP-1, COMP-2, COMP-3, COMP-4 e COMP-5, onde cada byte pode esconder uma criatura binária.

COMP-4 e COMP-5 sem Mistérios Abrir artigo ↗
⚓

Descendo aos arquivos do mainframe...

sexta-feira, 18 de agosto de 2023

EBCDIC: O Código que o Mundo Chama de Legado, Mas que Ainda Move Bilhões de Transações Todos os Dias

 

Bellacosa Mainframe iniciando no EBCDIC e cartão perfurado

☕ Um Café no Bellacosa Mainframe

EBCDIC: O Código que o Mundo Chama de Legado, Mas que Ainda Move Bilhões de Transações Todos os Dias

"Quem ri do EBCDIC normalmente nunca precisou garantir que um banco inteiro fechasse o balanço sem perder um único centavo."

Existe um momento na vida de praticamente todo programador que começa a trabalhar com Mainframe.

Você recebe um arquivo vindo do z/OS.

Abre no Notepad.

E aparece algo parecido com isto:

ÁêØ¢ËÑÇ@@@âÑÄÅ...

A primeira reação costuma ser:

"O arquivo está corrompido."

A segunda:

"Alguém esqueceu de salvar em UTF-8."

A terceira:

"Isso é tecnologia dos dinossauros."

Nenhuma delas está correta.

Na verdade, aquele arquivo está absolutamente perfeito.

O problema é que você está tentando ler um livro escrito em outro alfabeto.

Esse alfabeto chama-se EBCDIC (Extended Binary Coded Decimal Interchange Code).

E, apesar de muita gente tratá-lo como uma curiosidade histórica, ele continua presente nos maiores bancos, seguradoras, governos e companhias aéreas do planeta.

Hoje vamos tomar um café e desmistificar um dos assuntos mais mal compreendidos do universo IBM Z.


Bellacosa Mainframe apresenta o ebcdic

O maior mito sobre o EBCDIC

Pergunte para dez desenvolvedores que nunca trabalharam com Mainframe:

"Por que existe EBCDIC?"

As respostas costumam ser parecidas.

"Porque a IBM queria prender os clientes."

É uma boa história.

Mas é falsa.

Quando o EBCDIC nasceu, em 1963, praticamente ninguém utilizava ASCII.

Aliás...

Nem mesmo o ASCII era um padrão consolidado.

Cada fabricante possuía sua própria codificação.

Burroughs.

Honeywell.

CDC.

UNIVAC.

ICL.

Todos tinham soluções próprias.

A IBM simplesmente continuou evoluindo aquilo que ela já utilizava desde os computadores baseados em cartões perfurados.

Não era uma conspiração.

Era evolução tecnológica.


O mundo era completamente diferente

Hoje pensamos em computadores conectados pela Internet.

Em 1963...

Não havia Internet.

Não havia Wi-Fi.

Não havia APIs.

Não havia JSON.

Muito menos ChatGPT.

O computador era uma máquina corporativa.

Seu trabalho era processar:

  • folhas de pagamento;

  • contas bancárias;

  • extratos;

  • impostos;

  • seguros;

  • notas fiscais;

  • cartões perfurados.

O objetivo não era conversar com outros computadores.

Era processar documentos com absoluta confiabilidade.

Essa diferença muda tudo.


ASCII nasceu para conversar

O ASCII descende do Código Baudot, criado para telegrafia.

Imagine um cabo atravessando centenas de quilômetros.

Cada bit enviado custava tempo.

Tempo custava dinheiro.

Por isso o ASCII foi pensado para transmissão serial.

Seu projeto privilegiava simplicidade eletrônica.

Existe uma curiosidade fantástica.

Observe:

A = 65
a = 97

A diferença entre as duas letras é praticamente um único bit.

Isso permitia que um circuito eletrônico transformasse letras maiúsculas em minúsculas simplesmente alterando um sinal elétrico.

Hoje parece detalhe.

Na época era genial.


Enquanto isso...

Na IBM...

O problema era outro.

Ela precisava representar cartões perfurados.

E aí entra um personagem quase esquecido da computação moderna.


Bellacosa Mainframe e a anatomia de um cartão perfurado


O cartão perfurado

Imagine uma folha de papel rígido.

Ela possui 80 colunas.

Cada coluna representa um caractere.

Cada coluna possui 12 posições possíveis para perfuração.

12
11
0
1
2
3
4
5
6
7
8
9

As três primeiras posições eram chamadas de Zona.

As demais eram os Dígitos.

Para escrever uma letra não bastava perfurar um único lugar.

Era necessário combinar uma zona com um dígito.

Por exemplo:

Zona 12 + Dígito 1 = A

Esse padrão tornou-se tão importante que a IBM decidiu preservá-lo quando criou o System/360.


O nascimento do EBCDIC

Em vez de inventar um alfabeto completamente novo...

A IBM fez algo extremamente inteligente.

Ela traduziu a lógica física do cartão diretamente para um byte.

Cada caractere passou a ocupar:

4 bits
+
4 bits

Ou seja:

Nibble superior
↓

Zona

Nibble inferior
↓

Dígito

É por isso que o EBCDIC parece "bagunçado".

Na verdade...

Ele apenas respeita a lógica física do cartão.


O famoso buraco entre I e J

Essa é uma das primeiras coisas que um curioso percebe.

No ASCII temos:

ABCDEFGHIJKLMN...

Tudo contínuo.

Já no EBCDIC acontece algo diferente.

As letras ficam divididas em blocos.

A até I

↓

salto

↓

J até R

↓

salto

↓

S até Z

Por quê?

Porque era exatamente assim que funcionava o cartão perfurado.

O que parece estranho hoje fazia todo sentido em 1964.


O EBCDIC não é uma tabela.

Ele é uma filosofia.

Essa talvez seja a maior diferença.

ASCII resolve um problema.

Representar caracteres.

O EBCDIC fazia parte de uma arquitetura inteira.

Quando a IBM lançou o System/360 ela criou uma plataforma capaz de durar décadas.

E conseguiu.

Hoje, mais de sessenta anos depois, conceitos daquela arquitetura continuam presentes no IBM Z.

Entre eles:

  • canais de I/O;

  • processamento batch;

  • registros de tamanho fixo;

  • decimal compactado;

  • formatos de impressão;

  • arquivos VSAM;

  • e o EBCDIC.

Nada disso surgiu isoladamente.

Tudo fazia parte da mesma visão de engenharia.


"Então por que não mudar para UTF-8?"

Essa pergunta aparece em praticamente toda palestra.

A resposta curta é:

Porque não faz sentido.

Imagine um banco.

Ele possui cinquenta anos de software.

Bilhões de linhas em:

  • COBOL;

  • PL/I;

  • Assembler.

Agora imagine alterar a representação interna dos caracteres.

O que precisaria ser testado?

Tudo.

Literalmente tudo.

Comparações.

Ordenações.

Relatórios.

Impressoras.

Interfaces.

Conversões.

Milhões de programas.

Décadas de auditoria.

Bilhões de registros históricos.

O custo seria gigantesco.

O benefício?

Praticamente nenhum.


O IBM Z odeia UTF-8?

Muito pelo contrário.

Esse é outro mito.

Hoje o IBM Z executa naturalmente:

  • Java;

  • Python;

  • Node.js;

  • Go;

  • C/C++;

  • OpenJDK;

  • OpenSSH;

  • Linux on Z;

  • Docker;

  • Kubernetes;

  • APIs REST;

  • GraphQL;

  • OpenAPI.

Todos utilizando UTF-8.

O segredo está na arquitetura.

As aplicações modernas trabalham em UTF-8.

Os componentes tradicionais continuam utilizando EBCDIC.

Entre eles:

  • COBOL;

  • CICS;

  • IMS;

  • DB2;

  • arquivos sequenciais.

No meio do caminho existem conversores.

Tudo acontece automaticamente.

Na maioria das vezes o desenvolvedor nem percebe.


Um exemplo simples

Imagine um aplicativo no celular.

Cliente

↓

API REST

↓

z/OS Connect

↓

COBOL

↓

DB2

O celular envia UTF-8.

O z/OS Connect converte.

O COBOL recebe EBCDIC.

Na volta acontece exatamente o contrário.

Para quem usa o aplicativo...

Nada muda.


Curiosidade nº 1

Existe apenas um EBCDIC?

Não.

Existem centenas.

São chamadas de Code Pages.

Algumas famosas:

  • CP037

  • CP500

  • CP273

  • CP1047

  • CP1140

Cada uma adapta caracteres para determinados idiomas.

É parecido com as antigas páginas de código do Windows.


Curiosidade nº 2

Nem todo problema é "EBCDIC".

Muitas vezes o arquivo já está em EBCDIC.

Mas você está usando a página errada.

É como abrir um texto em português utilizando uma fonte chinesa.

Os bytes continuam corretos.

A interpretação é que muda.


Curiosidade nº 3

COBOL também depende do EBCDIC.

Quando você escreve:

IF CLIENTE-A > CLIENTE-B

Ou executa:

SORT

Existe uma sequência de classificação.

Essa sequência depende da codificação utilizada.

No Mainframe ela normalmente segue o EBCDIC.

Isso significa que uma ordenação feita no Windows pode produzir resultados diferentes daquela executada no z/OS.


Curiosidade nº 4

No ASCII:

9

↓

A

↓

a

No EBCDIC...

A ordem muda.

Esse pequeno detalhe já causou inúmeros bugs em integrações entre plataformas.


Curiosidade nº 5

Você provavelmente usa EBCDIC sem perceber.

Quando um banco expõe uma API REST.

Quando um PIX consulta uma conta.

Quando um cartão de crédito é autorizado.

Quando uma companhia aérea consulta uma reserva.

Quando um caixa eletrônico responde.

Existe uma enorme chance de existir um programa COBOL falando EBCDIC em algum lugar da infraestrutura.


Easter Egg para Padawans 🥚

Se você assistir ao filme Apollo 13, verá computadores IBM em operação.

Se visitar museus de computação encontrará cartões perfurados.

Se estudar a arquitetura do System/360 descobrirá que muitas decisões tomadas naquela época continuam influenciando os processadores IBM Z atuais.

É como encontrar fósseis vivos.

Só que ainda processando bilhões de dólares por dia.


Outro Easter Egg

O EBCDIC costuma ser chamado de "dinossauro".

Mas existe uma ironia divertida.

Grande parte das aplicações modernas utiliza JSON.

JSON é texto.

Texto precisa de codificação.

Sem um padrão de caracteres...

Nem mesmo APIs modernas existiriam.

No fim das contas...

Todo sistema continua dependendo de um "alfabeto".

A diferença é apenas qual deles.


Dicas para quem está começando no Mainframe

Nunca abra arquivos EBCDIC diretamente no Notepad.

Use ferramentas que suportem conversão.


Aprenda a diferença entre arquivo texto e arquivo binário.

Nem tudo pode ser convertido.

Campos COMP, COMP-3 e binários jamais devem ser tratados como texto.


Conheça sua Code Page.

CP037 não é igual à CP1047.

Esse detalhe salva horas de investigação.


Aprenda como funciona FTP ASCII e FTP Binary.

Uma configuração incorreta pode "corromper" um arquivo apenas durante a transferência.

Na verdade, o arquivo original continua íntegro.


Não tenha medo do EBCDIC.

Ele parece estranho apenas porque crescemos utilizando ASCII e UTF-8.

Depois de alguns dias convivendo com Mainframe ele se torna completamente natural.


O verdadeiro legado do EBCDIC

Existe uma frase famosa na engenharia:

"Se algo funciona perfeitamente há cinquenta anos, talvez exista uma boa razão para não mexer."

O EBCDIC sobreviveu não porque o mercado ficou parado.

Mas porque ele faz parte de uma arquitetura extremamente estável.

Enquanto tecnologias aparecem e desaparecem a cada cinco anos...

O IBM Z continua processando alguns dos sistemas mais críticos do planeta.

Não porque seja antigo.

Mas porque foi projetado para durar.


Um Café Antes de Ir...

O programador júnior normalmente olha para o EBCDIC e enxerga um problema.

O desenvolvedor experiente enxerga compatibilidade.

O arquiteto enxerga engenharia.

E o engenheiro de Mainframe enxerga algo ainda maior: uma decisão de projeto que atravessou gerações sem interromper negócios, preservando décadas de investimentos e garantindo que milhões de pessoas possam sacar dinheiro, comprar passagens, pagar contas e realizar transações todos os dias.

Da próxima vez que você abrir um arquivo EBCDIC e encontrar uma "sopa de caracteres", lembre-se: o arquivo não está errado. Apenas está falando a língua nativa de um dos ecossistemas computacionais mais robustos já construídos.

Porque, no fim das contas, o EBCDIC nunca foi um obstáculo ao futuro. Ele sempre foi a ponte silenciosa entre mais de 60 anos de história da computação e o IBM Z que continua sustentando o mundo digital de hoje.

E essa, meu colega Padawan, é uma das maiores lições que o Mainframe pode ensinar: boas arquiteturas envelhecem muito melhor do que modismos tecnológicos. ☕


domingo, 7 de agosto de 2022

The Wild Wild COBOL — Quando James West Embarcou no Trem do z/OS, Artemus Gordon Vestiu um COMP-3 e o Dr. Loveless Tentou Sabotar a PROCEDURE DIVISION

 

Bellacosa Mainframe e as quatro divisoes do cobol

☕ Um Café no Bellacosa Mainframe

The Wild Wild COBOL — Quando James West Embarcou no Trem do z/OS, Artemus Gordon Vestiu um COMP-3 e o Dr. Loveless Tentou Sabotar a PROCEDURE DIVISION

Ou: o jovem padawan COBOL descobriu que as quatro divisões não são quatro fases de execução, um arquivo não é apenas um arquivo, WORKING-STORAGE não é um depósito de velharias — e nenhum agente secreto deveria atualizar o saldo antes de verificar o FILE STATUS



Prólogo — O trem que entrou no datacenter

Ano de 1965.

Enquanto o mundo assistia à Guerra Fria, à corrida espacial e à multiplicação de computadores empresariais, a televisão americana colocava nos trilhos uma série estranhíssima.

The Wild Wild West misturava faroeste, espionagem, ficção científica, invenções impossíveis, vilões megalomaníacos e agentes secretos que viajavam a bordo de um trem equipado como uma agência móvel de inteligência.

James West, interpretado por Robert Conrad, era o homem da ação. Artemus Gordon, vivido por Ross Martin, era inventor, estrategista e mestre dos disfarces. Ambos protegiam o presidente Ulysses S. Grant contra planos que normalmente começavam com uma pequena engrenagem e terminavam com alguma máquina destinada a dominar o país.

A série estreou em 17 de setembro de 1965 e durou quatro temporadas, com 104 episódios. A ideia era mais ou menos colocar “James Bond a cavalo”, acrescentar um laboratório dentro de um trem e soltar o Dr. Miguelito Loveless no ambiente de produção. The Wild Wild West — série de 1965

Agora imagine que James West receba uma nova missão:

“Agente West, alguém está alterando operações bancárias dentro do mainframe. O suspeito deixou quatro palavras na cena do crime: IDENTIFICATION, ENVIRONMENT, DATA e PROCEDURE.”

West verifica o revólver.

Artemus ajusta os óculos.

No fundo, começa a trilha de Richard Markowitz, misturando jazz, aventura e música de faroeste.

O trem parte para o datacenter.



1. Afinal, como “pensa” um programa COBOL?

Dizer que um programa “pensa” é uma metáfora.

O programa não possui consciência, intenção ou compreensão do negócio. Ele não olha para um campo chamado SALDO-CLIENTE e sente preocupação com o correntista.

O que ele faz é:

  1. receber ou acessar dados;

  2. interpretá-los conforme suas definições;

  3. executar instruções;

  4. verificar condições;

  5. alterar estados;

  6. produzir resultados;

  7. informar sucesso ou erro ao ambiente.

Por isso, uma definição mais precisa seria:

Um programa COBOL processa informações segundo contratos de dados e regras procedurais previamente definidas.

Sua famosa organização em quatro divisões responde a quatro perguntas:

DivisãoPergunta
IDENTIFICATION DIVISIONQuem sou?
ENVIRONMENT DIVISIONCom quais recursos externos trabalharei?
DATA DIVISIONComo minhas informações estão organizadas?
PROCEDURE DIVISIONO que devo fazer?

A IBM continua documentando essa estrutura no Enterprise COBOL moderno. As quatro divisões organizam o programa-fonte, embora nem todas precisem conter a mesma quantidade de elementos em todos os programas. IBM — COBOL program structure

Mas aqui encontramos a primeira armadilha do Dr. Loveless:

As quatro divisões não são quatro etapas executadas uma depois da outra.

O computador não executa a IDENTIFICATION DIVISION, entra na ENVIRONMENT DIVISION, passeia pela DATA DIVISION e finalmente chega à PROCEDURE DIVISION.

As três primeiras são essencialmente declarativas. Elas fornecem informações para que o compilador compreenda o programa.

A execução das instruções acontece na PROCEDURE DIVISION.

As quatro divisões são os compartimentos do trem. A PROCEDURE DIVISION é a locomotiva.



2. IDENTIFICATION DIVISION: os documentos do agente

Todo agente precisa de uma identidade:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. PROCESSA-OPERACOES.

O elemento central é o PROGRAM-ID, que identifica a unidade de programa.

Em códigos mais antigos, podemos encontrar:

       AUTHOR. VAGNER BELLACOSA.
       INSTALLATION. BANCO-WILD-WEST.
       DATE-WRITTEN. 1965-09-17.

Esses parágrafos documentais foram mais importantes em uma época anterior a Git, Endevor, Changeman, ISPW e outros sistemas de controle de versão e gerenciamento do ciclo de vida.

Hoje, manter um histórico completo de alterações dentro do fonte costuma provocar blocos enormes de comentários:

      * ALTERADO POR FULANO EM 1987
      * ALTERADO POR SICRANO EM 1994
      * ALTERADO NOVAMENTE EM 2001
      * NINGUÉM SABE QUEM ALTEROU EM 2007

Esse tipo de comentário pode ser útil, mas não substitui um repositório confiável.

O que a divisão não faz

Ela não é executada como uma rotina.

O programa não começa dizendo:

Olá, sistema operacional.
Meu nome é PROCESSA-OPERACOES.
Fui escrito por Vagner.

Sua função principal é identificar o programa para o compilador e para o ecossistema de desenvolvimento.

Dica do agente West

Ao analisar um fonte desconhecido, procure primeiro:

       PROGRAM-ID.

Depois procure:

  • comentários iniciais;

  • descrição funcional;

  • nomes de copybooks;

  • PROCEDURE DIVISION USING;

  • programas chamados;

  • comandos CICS ou SQL.

O PROGRAM-ID mostra o nome. As interfaces mostram quem o programa realmente é.

Easter egg número 1

O programa de exemplo poderia se chamar:

       PROGRAM-ID. NIGHT-OF-THE-COMP3.

Os episódios de The Wild Wild West frequentemente começavam com “The Night of...”. Portanto, “The Night of the Packed Decimal” seria um episódio perfeitamente plausível no datacenter Bellacosa.



3. ENVIRONMENT DIVISION: o trem e os trilhos

James West e Artemus Gordon viajavam em seu próprio trem, o Wanderer, equipado com aposentos, armas, dispositivos e laboratório.

O trem era a plataforma operacional dos agentes.

No COBOL, a ENVIRONMENT DIVISION ajuda a descrever como o programa se relaciona com seu ambiente e, particularmente, com os arquivos utilizados.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.

           SELECT ARQUIVO-ENTRADA
               ASSIGN TO TRANSIN
               ORGANIZATION IS SEQUENTIAL
               FILE STATUS IS WS-STATUS-ENTRADA.

           SELECT ARQUIVO-SAIDA
               ASSIGN TO TRANSOUT
               ORGANIZATION IS SEQUENTIAL
               FILE STATUS IS WS-STATUS-SAIDA.

Aqui existem diferentes níveis de nome:

  • ARQUIVO-ENTRADA: nome lógico conhecido pelo programa;

  • TRANSIN: ligação externa;

  • dataset: recurso físico fornecido durante a execução.

O JCL poderia conter:

//STEP01   EXEC PGM=PROCESSA
//STEPLIB  DD DSN=BANCO.LOADLIB,DISP=SHR
//TRANSIN  DD DSN=BANCO.OPERACOES.ENTRADA,DISP=SHR
//TRANSOUT DD DSN=BANCO.OPERACOES.SAIDA,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(10,5))

O programa não precisa ter o nome físico BANCO.OPERACOES.ENTRADA gravado dentro do fonte.

Ele pede TRANSIN.

O ambiente entrega o dataset correspondente.

Isso permite executar o mesmo programa com diferentes arquivos:

//TRANSIN DD DSN=BANCO.OPERACOES.20260829,DISP=SHR

ou:

//TRANSIN DD DSN=BANCO.OPERACOES.20260830,DISP=SHR

Nenhuma recompilação é necessária.

Isso parece moderno?

É uma forma antiga e muito eficiente de separar:

  • código;

  • configuração;

  • recurso físico;

  • execução.

Em linguagens modernas, talvez alguém chamasse isso de configuração externa, abstração de recursos ou injeção de dependência.

No mainframe, o jovem padawan encontra o conceito dentro de um JCL escrito quando “cloud-native” ainda poderia significar um índio olhando para as nuvens antes de uma tempestade.

O contrato entre três partes

ParticipanteResponsabilidade
COBOLDeclara o nome lógico e a forma de acesso
JCL ou subsistemaAssocia o nome lógico ao recurso
Sistema operacionalExecuta e controla o I/O

Curiosidade

A ENVIRONMENT DIVISION não descreve tudo sobre o ambiente de produção.

Ela não contém necessariamente:

  • capacidade da LPAR;

  • política do WLM;

  • regras RACF;

  • configuração do sysplex;

  • parâmetros do CICS;

  • velocidade dos discos;

  • prioridade do job;

  • quantidade de memória disponível.

Por isso, dizer que ela “descreve onde o programa será executado” é didaticamente aceitável, mas amplo demais.

Ela descreve aspectos do ambiente relevantes ao COBOL, especialmente a relação com arquivos e dispositivos lógicos.



4. DATA DIVISION: o laboratório de Artemus Gordon

Artemus Gordon era o inventor e mestre dos disfarces.

Ele podia entrar num episódio como vendedor, cientista, militar, médico ou personagem improvável. O homem mudava a aparência, mas continuava sendo Artemus.

A DATA DIVISION possui algo dessa natureza: ela informa como sequências de bytes devem ser interpretadas.

Os mesmos bytes podem representar:

  • caracteres;

  • números;

  • datas;

  • valores monetários;

  • chaves;

  • indicadores;

  • registros;

  • tabelas;

  • áreas recebidas de outros programas.

A DATA DIVISION não é apenas um depósito de variáveis. É o laboratório onde bytes recebem forma e significado.

Ela pode conter seções como:

  • FILE SECTION;

  • WORKING-STORAGE SECTION;

  • LOCAL-STORAGE SECTION;

  • LINKAGE SECTION.

Cada uma responde a uma necessidade diferente.


4.1 FILE SECTION: a planta dos vagões

A ENVIRONMENT DIVISION informa como localizar o trem.

A FILE SECTION informa como cada vagão está organizado.

       DATA DIVISION.
       FILE SECTION.

       FD  ARQUIVO-ENTRADA
           RECORDING MODE IS F.

       01  REGISTRO-ENTRADA.
           05  IN-TIPO-OPERACAO     PIC X.
           05  IN-NUMERO-CONTA      PIC 9(10).
           05  IN-VALOR             PIC 9(11)V99.
           05  IN-DATA              PIC 9(8).
           05  IN-IDENTIFICADOR     PIC X(20).

O FD, ou File Description, descreve o arquivo para o programa.

O nível 01 descreve cada registro lido.

A diferença é importante:

ElementoFunção
SELECTDeclara a relação lógica com o arquivo
FDDescreve características do arquivo
Registro 01Define o layout dos dados
JCL DDFornece o dataset físico

O perigo do vagão deslocado

Imagine que o arquivo contenha:

C00012345670000000012500020260830ABC123

Se o layout estiver deslocado por uma posição, o programa pode interpretar:

  • parte da conta como valor;

  • parte do valor como data;

  • parte da data como identificador.

O arquivo existe. O job pode até começar. Mas os significados estarão errados.

Esse é um dos grandes ensinamentos do COBOL:

Dados não são apenas conteúdo; são conteúdo, posição, tamanho, formato e contexto.


4.2 WORKING-STORAGE SECTION: a bancada permanente

       WORKING-STORAGE SECTION.

       01  WS-CONTADORES.
           05  WS-REGISTROS-LIDOS       PIC 9(9) VALUE ZERO.
           05  WS-APROVADOS             PIC 9(9) VALUE ZERO.
           05  WS-REJEITADOS            PIC 9(9) VALUE ZERO.

       01  WS-TOTAL-PROCESSADO           PIC S9(13)V99 COMP-3
                                         VALUE ZERO.

       01  WS-STATUS-ENTRADA             PIC XX.
       01  WS-STATUS-SAIDA               PIC XX.

A WORKING-STORAGE guarda dados internos necessários ao processamento:

  • contadores;

  • acumuladores;

  • indicadores;

  • mensagens;

  • resultados intermediários;

  • chaves de pesquisa;

  • códigos de retorno;

  • áreas auxiliares;

  • tabelas internas.

Ela é a bancada de Artemus Gordon: engrenagens, tubos, ferramentas, documentos e explosivos que Igor jurou serem apenas “materiais de homologação”.

Cuidado com uma simplificação perigosa

Muitos iniciantes imaginam que a WORKING-STORAGE sempre nasce completamente limpa toda vez que o programa é chamado.

Isso não deve ser presumido sem compreender:

  • o ambiente de execução;

  • o ciclo de vida do módulo;

  • se o programa é inicial;

  • se é chamado repetidamente;

  • se utiliza IS INITIAL;

  • se há reutilização da área.

O comportamento da WORKING-STORAGE importa especialmente em subprogramas, aplicações residentes e ambientes CICS.

A regra prática é:

Inicialize explicitamente aquilo cujo valor inicial seja importante para a lógica.

       INITIALIZE WS-CONTADORES
                  WS-TOTAL-PROCESSADO

Mas também compreenda o que INITIALIZE fará com cada categoria de campo. Não transforme o comando numa varinha mágica usada sem ler o layout.


4.3 LOCAL-STORAGE SECTION: uma bancada para cada missão

       LOCAL-STORAGE SECTION.

       01  LS-CONTADOR-TEMPORARIO       PIC 9(4).
       01  LS-VALOR-INTERMEDIARIO        PIC S9(9)V99 COMP-3.

A LOCAL-STORAGE é alocada a cada entrada no programa e liberada quando a execução retorna.

Ela é útil quando diferentes ativações precisam de áreas independentes, especialmente em situações recursivas ou reentrantes.

Podemos imaginar assim:

  • WORKING-STORAGE: laboratório instalado no trem;

  • LOCAL-STORAGE: maleta nova entregue para esta missão;

  • LINKAGE: documento recebido de outro agente.

A IBM distingue essas áreas pelo modo como o armazenamento é obtido e pelo ciclo de vida dos dados. IBM — Describing the data


4.4 LINKAGE SECTION: a mensagem secreta de Washington

       LINKAGE SECTION.

       01  LK-OPERACAO.
           05  LK-CONTA                 PIC 9(10).
           05  LK-VALOR                 PIC S9(11)V99 COMP-3.
           05  LK-TIPO                  PIC X.
           05  LK-CODIGO-RETORNO        PIC XX.

A LINKAGE SECTION descreve dados disponibilizados por outro componente.

       PROCEDURE DIVISION USING LK-OPERACAO.

O programa chamado conhece o layout, mas normalmente não é o proprietário original da área.

Outro programa poderia executar:

       CALL 'VALOPER'
           USING WS-OPERACAO

O programa VALOPER receberia a área por meio da LINKAGE SECTION.

A metáfora correta

James West recebe uma mensagem cifrada do presidente Grant.

Ele não criou o papel.

Não é dono da pasta.

Mas precisa conhecer a estrutura da mensagem para interpretá-la.

A LINKAGE SECTION descreve essa mensagem.

Perigo de produção

Chamador e chamado precisam concordar sobre:

  • tamanho da área;

  • ordem dos campos;

  • representação;

  • sinal;

  • quantidade de casas decimais;

  • forma de passagem;

  • campos de retorno.

Se um programa define:

       05 VALOR PIC S9(7)V99 COMP-3.

e outro acredita receber:

       05 VALOR PIC X(20).

Artemus Gordon pode usar todos os disfarces disponíveis: o contrato continua incompatível.



5. PICTURE: o código secreto dos dados

Considere:

       05  WS-VALOR              PIC S9(7)V99 COMP-3.

Esse campo diz muito mais do que “sou um número”.

  • S: possui sinal;

  • 9(7): comporta sete dígitos inteiros;

  • V: possui ponto decimal implícito;

  • 99: possui duas casas decimais;

  • COMP-3: usa representação decimal compactada.

O V não ocupa um byte físico. Ele informa a posição lógica do separador decimal.

Se o campo contiver os dígitos equivalentes a:

000012345

o COBOL poderá tratá-los como:

1.234,45

conforme o PICTURE.

Por que isso importa aos bancos?

Valores financeiros precisam de precisão decimal previsível.

Usar ponto flutuante binário indiscriminadamente pode introduzir aproximações inconvenientes para dinheiro. COBOL oferece representações de ponto fixo, e itens COMP-3 são tratados como decimais compactados para operações aritméticas. IBM — Numeric data formats

COMP-3 não é o cofre do presidente Grant

Ele não impede automaticamente:

  • estouro;

  • truncamento;

  • arredondamento indevido;

  • dado inválido;

  • erro de sinal;

  • campo insuficiente;

  • regra financeira incorreta.

Por exemplo:

       01 WS-PEQUENO PIC 9(3).

O campo só comporta três dígitos. Tentar colocar um valor maior exige compreender o comportamento da operação e as opções de compilação.

Dica Bellacosa

Para dinheiro, não pergunte apenas:

“Quantos bytes esse campo ocupa?”

Pergunte também:

  • qual é a moeda?

  • quantas casas decimais?

  • pode ser negativo?

  • qual é o maior valor permitido?

  • qual regra de arredondamento?

  • zero é válido?

  • espaços são possíveis na entrada?

  • dados negativos representam débito ou estorno?

O tipo físico é apenas metade do contrato. A semântica empresarial é a outra.



6. Níveis de dados: o trem dentro do trem

Os números 01, 05 e 10 indicam hierarquia:

       01  CLIENTE.
           05  CLIENTE-ID                 PIC 9(10).
           05  CLIENTE-NOME.
               10  CLIENTE-PRIMEIRO-NOME PIC X(20).
               10  CLIENTE-SOBRENOME     PIC X(30).
           05  CLIENTE-ENDERECO.
               10  CLIENTE-RUA           PIC X(40).
               10  CLIENTE-NUMERO        PIC 9(6).
               10  CLIENTE-CEP           PIC 9(8).

CLIENTE é um grupo.

CLIENTE-NOME é um subgrupo.

CLIENTE-SOBRENOME é um campo elementar.

Podemos mover o grupo:

       MOVE CLIENTE-NOME TO NOME-IMPRESSAO

ou somente uma parte:

       MOVE CLIENTE-SOBRENOME
         TO SOBRENOME-IMPRESSAO

COBOL permite trabalhar com o registro completo e com suas partes.

Curiosidade: nome qualificado

Se existirem dois campos chamados NUMERO:

       NUMERO OF CLIENTE-ENDERECO

podemos qualificá-los por sua estrutura superior.

Isso demonstra que o nome de um campo também pode depender de seu contexto.


7. Nível 88: quando um código vira regra de negócio

Veja:

       01  WS-FIM-ARQUIVO             PIC X VALUE 'N'.
           88  FIM-DO-ARQUIVO         VALUE 'S'.
           88  HA-REGISTROS           VALUE 'N'.

O nível 88 cria nomes de condição.

Em vez de:

       IF WS-FIM-ARQUIVO = 'S'

podemos usar:

       IF FIM-DO-ARQUIVO

Outro exemplo:

       01  WS-STATUS-CONTA            PIC X.
           88  CONTA-ATIVA            VALUE 'A'.
           88  CONTA-BLOQUEADA        VALUE 'B'.
           88  CONTA-ENCERRADA        VALUE 'E'.

A lógica torna-se expressiva:

       IF CONTA-BLOQUEADA
           MOVE 'OPERACAO NAO PERMITIDA'
             TO WS-MENSAGEM
       END-IF

O nível 88 não costuma reservar outra área independente. Ele atribui significado a valores da variável associada.

O disfarce de Artemus Gordon

O byte físico contém B.

Para o computador, é um caractere.

Para o programa, significa CONTA-BLOQUEADA.

Para o negócio, significa que determinadas operações precisam ser impedidas.

Artemus não alterou o byte. Alterou a maneira pela qual nós o compreendemos.



8. PROCEDURE DIVISION: James West entra em ação

Aqui ficam as instruções executáveis:

       PROCEDURE DIVISION.

       0000-PRINCIPAL.
           PERFORM 1000-INICIALIZAR

           PERFORM 2000-PROCESSAR
               UNTIL FIM-DO-ARQUIVO

           PERFORM 3000-FINALIZAR

           GOBACK.

A estrutura revela um programa batch clássico:

  1. inicializar;

  2. processar;

  3. finalizar;

  4. devolver o controle.

       1000-INICIALIZAR.
           OPEN INPUT  ARQUIVO-ENTRADA
                OUTPUT ARQUIVO-SAIDA

           IF WS-STATUS-ENTRADA NOT = '00'
               DISPLAY 'ERRO NA ABERTURA: '
                       WS-STATUS-ENTRADA
               MOVE 12 TO RETURN-CODE
               GOBACK
           END-IF

           PERFORM 1100-LER-ENTRADA.

Depois:

       2000-PROCESSAR.
           PERFORM 2100-VALIDAR

           IF OPERACAO-VALIDA
               PERFORM 2200-EFETIVAR
           ELSE
               PERFORM 2300-REJEITAR
           END-IF

           PERFORM 2400-GRAVAR-RESULTADO
           PERFORM 1100-LER-ENTRADA.

No final:

       3000-FINALIZAR.
           CLOSE ARQUIVO-ENTRADA
                 ARQUIVO-SAIDA

           DISPLAY 'LIDOS:      ' WS-REGISTROS-LIDOS
           DISPLAY 'APROVADOS:  ' WS-APROVADOS
           DISPLAY 'REJEITADOS: ' WS-REJEITADOS.

O erro do iniciante

O iniciante pode acreditar que o COBOL começa executando o primeiro parágrafo visualmente encontrado em qualquer ponto do fonte.

A execução começa na primeira instrução executável da PROCEDURE DIVISION, salvo particularidades e pontos de entrada definidos.

Organizar um parágrafo não é chamá-lo.

Este parágrafo:

       EXPLODIR-TREM.
           DISPLAY 'BOOM'.

não será executado apenas porque existe. Ele precisa ser alcançado pelo fluxo, por exemplo:

       PERFORM EXPLODIR-TREM

Igor agradece a informação.



9. O ciclo clássico: ler, testar, processar, ler novamente

Um programa sequencial costuma seguir este modelo:

       PERFORM LER-ENTRADA

       PERFORM UNTIL FIM-DO-ARQUIVO
           PERFORM PROCESSAR-REGISTRO
           PERFORM LER-ENTRADA
       END-PERFORM

A primeira leitura ocorre antes do laço.

Isso garante que o programa só processe quando houver um registro disponível.

       LER-ENTRADA.
           READ ARQUIVO-ENTRADA
               AT END
                   SET FIM-DO-ARQUIVO TO TRUE
               NOT AT END
                   ADD 1 TO WS-REGISTROS-LIDOS
           END-READ.

O fim do arquivo não é necessariamente erro ou ABEND.

É uma condição esperada.

O programa lê até que o arquivo informe:

“Agente West, não existem mais passageiros.”

Então finaliza o processamento.

flowchart TD
    A["Abrir arquivos"] --> B["Ler registro"]
    B --> C{"Fim do arquivo?"}
    C -- Não --> D["Validar e processar"]
    D --> E["Gravar resultado"]
    E --> B
    C -- Sim --> F["Fechar e emitir totais"]

A armadilha do último registro

Se o programa processar antes da primeira leitura, trabalhará com uma área ainda não preenchida corretamente.

Se esquecer a leitura ao final do laço, processará o mesmo registro para sempre.

O resultado pode ser um laço infinito, alto consumo de CPU ou um job aparentemente decidido a atravessar o continente sem parar em nenhuma estação.



10. O verdadeiro pensamento: estados e condições

Um programa COBOL não trabalha somente com linhas. Ele trabalha com estados:

  • arquivo fechado;

  • arquivo aberto;

  • registro disponível;

  • fim do arquivo;

  • operação válida;

  • operação rejeitada;

  • atualização pendente;

  • commit realizado;

  • rollback solicitado.

Considere:

       EVALUATE TRUE
           WHEN IN-CONTA = ZERO
               PERFORM REJEITAR-CONTA
           WHEN IN-VALOR <= ZERO
               PERFORM REJEITAR-VALOR
           WHEN IN-VALOR > WS-LIMITE
               PERFORM ANALISAR-LIMITE
           WHEN OTHER
               PERFORM APROVAR-OPERACAO
       END-EVALUATE

O EVALUATE TRUE permite expressar uma cadeia organizada de condições.

Também podemos avaliar um campo diretamente:

       EVALUATE IN-TIPO-OPERACAO
           WHEN 'C'
               PERFORM PROCESSAR-CREDITO
           WHEN 'D'
               PERFORM PROCESSAR-DEBITO
           WHEN 'E'
               PERFORM PROCESSAR-ESTORNO
           WHEN OTHER
               PERFORM REJEITAR-TIPO
       END-EVALUATE

O WHEN OTHER é a porta dos fundos.

Se ele não existir, uma entrada inesperada pode passar sem o tratamento necessário.

A pergunta de produção

Ao depurar, não pergunte somente:

“Qual foi a última linha executada?”

Pergunte:

“Em que estado o programa acreditava estar?”

Um incidente frequentemente ocorre porque o estado real e o estado imaginado pelo programa divergiram.



11. FILE STATUS: a mensagem escondida no bolso do vilão

Ao declarar:

       FILE STATUS IS WS-STATUS-ENTRADA

o programa recebe informações sobre o resultado das operações de arquivo.

Depois de OPEN, READ, WRITE, REWRITE ou CLOSE, deve avaliar o código quando necessário.

       READ ARQUIVO-ENTRADA

       EVALUATE WS-STATUS-ENTRADA
           WHEN '00'
               CONTINUE
           WHEN '10'
               SET FIM-DO-ARQUIVO TO TRUE
           WHEN OTHER
               DISPLAY 'ERRO DE LEITURA: '
                       WS-STATUS-ENTRADA
               MOVE 12 TO RETURN-CODE
       END-EVALUATE

Os significados exatos dependem da organização e da operação, devendo ser consultados na documentação aplicável.

Não faça isso no saloon

       READ ARQUIVO-ENTRADA
       PERFORM PROCESSAR-REGISTRO

Sem verificar o resultado, o programa pode processar uma área não atualizada ou tratar um erro como se fosse sucesso.

James West nunca entraria num quarto escuro sem verificar a janela.

Igor entra, atualiza o VSAM e pergunta depois.



12. O programa bancário completo

Considere uma operação contendo:

  • tipo;

  • conta;

  • valor;

  • data;

  • identificador único.

O fluxo poderia ser:

  1. validar o tamanho e o formato;

  2. validar o tipo;

  3. verificar duplicidade;

  4. localizar a conta;

  5. verificar o estado da conta;

  6. conferir saldo ou limite;

  7. calcular o novo saldo;

  8. atualizar a conta;

  9. registrar auditoria;

  10. confirmar a unidade de trabalho;

  11. gerar a resposta.

Uma versão didática:

       PROCESSAR-OPERACAO.
           SET OPERACAO-VALIDA TO TRUE

           PERFORM VALIDAR-TIPO
           PERFORM VALIDAR-CONTA
           PERFORM VALIDAR-VALOR

           IF OPERACAO-VALIDA
               EVALUATE IN-TIPO-OPERACAO
                   WHEN 'C'
                       ADD IN-VALOR TO WS-SALDO
                       MOVE '00' TO OUT-CODIGO
                   WHEN 'D'
                       IF WS-SALDO >= IN-VALOR
                           SUBTRACT IN-VALOR
                             FROM WS-SALDO
                           MOVE '00' TO OUT-CODIGO
                       ELSE
                           MOVE '51' TO OUT-CODIGO
                       END-IF
                   WHEN OTHER
                       MOVE '12' TO OUT-CODIGO
               END-EVALUATE
           END-IF.

Mas este código ainda não representa um sistema financeiro completo.

Faltam assuntos como:

  • autorização;

  • concorrência;

  • bloqueio;

  • persistência;

  • duplicidade;

  • idempotência;

  • segurança;

  • auditoria;

  • commit;

  • rollback;

  • reconciliação;

  • recuperação após falha.

Idempotência: a mesma diligência não pode ser assaltada duas vezes

Se a mesma operação chegar novamente por causa de retry, o sistema precisa saber se deve repeti-la.

Um identificador único pode ajudar a reconhecer que ela já foi processada.

Sem isso, um retry de comunicação pode transformar um débito de R$100 em dois débitos de R$100.

O primeiro processamento foi correto.

O segundo também seguiu corretamente as instruções.

O resultado empresarial, porém, está errado.



13. COMMIT e ROLLBACK: quem fica com o dinheiro?

Em processamento transacional, alterar uma conta e registrar a operação precisam formar uma unidade coerente.

Imagine:

  1. debitar a conta;

  2. gravar o histórico;

  3. atualizar a auditoria;

  4. confirmar.

Se o sistema falhar entre os passos 1 e 2, o saldo poderia mudar sem existir histórico correspondente.

O controle transacional procura impedir esse tipo de estado parcial.

  • COMMIT: confirma as alterações;

  • ROLLBACK: desfaz alterações da unidade de trabalho ainda não confirmadas.

O Dr. Loveless do retry

O retry não é um mecanismo automaticamente bondoso.

Se uma operação falha antes da confirmação, talvez seja seguro repeti-la.

Se o cliente apenas não recebeu a resposta, mas a operação já foi confirmada, repeti-la pode duplicar o efeito.

Por isso, sistemas críticos precisam distinguir:

  • a solicitação não chegou;

  • chegou, mas falhou;

  • foi processada e sofreu rollback;

  • foi confirmada;

  • foi confirmada, mas a resposta se perdeu.

O agente competente não pergunta apenas “deu erro?”.

Ele pergunta:

“Em qual lado do COMMIT estávamos quando o trem explodiu?”


14. Em CICS, James West não percorre o arquivo inteiro

Num programa batch, o fluxo frequentemente percorre muitos registros.

Em CICS, uma transação normalmente recebe uma solicitação, executa uma unidade curta de processamento e responde.

       EXEC CICS READ
            FILE('CONTAS')
            INTO(WS-REGISTRO-CONTA)
            RIDFLD(WS-CHAVE-CONTA)
            UPDATE
            RESP(WS-RESP)
       END-EXEC

Depois:

       EVALUATE WS-RESP
           WHEN DFHRESP(NORMAL)
               PERFORM PROCESSAR-CONTA
           WHEN DFHRESP(NOTFND)
               PERFORM TRATAR-CONTA-INEXISTENTE
           WHEN OTHER
               PERFORM TRATAR-ERRO-CICS
       END-EVALUATE

Aqui, o código COBOL trabalha sob o controle de um gerenciador transacional.

O CICS participa de:

  • despacho da transação;

  • acesso a recursos;

  • controle de unidade de trabalho;

  • comunicação;

  • recuperação;

  • gerenciamento operacional.

COBOL não está sozinho no trem. O CICS é o chefe da ferrovia.



15. Com Db2, entra o especialista relacional

       EXEC SQL
           SELECT SALDO,
                  STATUS_CONTA
             INTO :WS-SALDO,
                  :WS-STATUS-CONTA
             FROM CONTAS
            WHERE NUMERO_CONTA = :WS-CONTA
       END-EXEC

Depois:

       EVALUATE SQLCODE
           WHEN ZERO
               PERFORM PROCESSAR-CONTA
           WHEN +100
               PERFORM TRATAR-NAO-ENCONTRADA
           WHEN OTHER
               PERFORM TRATAR-ERRO-DB2
       END-EVALUATE

COBOL cuida do fluxo procedural e das regras.

Db2 cuida do acesso relacional, dos dados, índices, planos e mecanismos internos.

O programa não precisa saber em qual página física está a linha. Precisa saber:

  • o que solicitou;

  • quais host variables receberão os valores;

  • qual foi o SQLCODE;

  • qual ação tomar.

Dica do Artemus

Nunca trate todo SQLCODE diferente de zero como a mesma coisa.

“Não encontrado”, “aviso”, “deadlock”, “timeout” e “erro estrutural” não significam a mesma situação operacional.

Um agente secreto que chama todos os desconhecidos de “Dr. Loveless” terminará prendendo o condutor do próprio trem.



16. O programa que escrevemos não é exatamente o programa executado

Antes da execução existe uma cadeia:

  1. expansão de copybooks;

  2. processamento de diretivas;

  3. tratamento de SQL, CICS ou outras extensões;

  4. compilação;

  5. geração do objeto;

  6. link-edit ou bind;

  7. criação do módulo de carga;

  8. carregamento;

  9. execução.

Quando escrevemos:

       COPY CPYCONTA.

o copybook é incorporado durante a preparação do fonte.

Quando escrevemos:

       ADD WS-VALOR TO WS-TOTAL

a CPU não executa a palavra inglesa ADD. O compilador gera instruções adequadas à arquitetura e às representações envolvidas.

COBOL descreve a intenção; o compilador produz a mecânica.

Compiladores modernos também podem otimizar o código para explorar recursos atuais do IBM Z. Portanto, um fonte com aparência antiga não significa necessariamente execução com técnicas de 1965.

O trem pode ser clássico. A locomotiva não precisa ser a vapor.


17. Antigo não significa automaticamente simples

Programas COBOL antigos podem conter:

  • REDEFINES;

  • OCCURS DEPENDING ON;

  • arquivos VSAM;

  • múltiplos índices;

  • chamadas dinâmicas;

  • SQL;

  • CICS;

  • IMS;

  • MQ;

  • tabelas complexas;

  • copybooks aninhados;

  • lógica gerada;

  • regras acumuladas por décadas.

Veja um REDEFINES:

       01  WS-RESPOSTA.
           05 WS-RESPOSTA-BRUTA       PIC X(20).

       01  WS-RESPOSTA-DETALHADA
           REDEFINES WS-RESPOSTA.
           05 WS-CODIGO               PIC XX.
           05 WS-MENSAGEM             PIC X(18).

As duas estruturas interpretam a mesma área de armazenamento.

Artemus Gordon continua sendo o mesmo homem, mas agora aparece com outro disfarce.

O recurso é poderoso. Também pode ficar difícil de rastrear quando usado sem disciplina.

OCCURS: a lista de passageiros

       01  WS-TABELA-TAXAS.
           05 WS-TAXA OCCURS 10 TIMES.
               10 WS-CODIGO-TAXA      PIC XX.
               10 WS-PERCENTUAL       PIC 9V9999.

Isso cria uma tabela com dez ocorrências.

Pode ser acessada assim:

       MOVE 'TX' TO WS-CODIGO-TAXA(1)

Em estruturas maiores, podem existir índices, pesquisas sequenciais e SEARCH ALL.

O iniciante deve entender que uma tabela COBOL não é um banco de dados. É uma estrutura repetida dentro de uma área de dados.



18. COBOL não é confiável por encantamento

A linguagem favorece descrições explícitas e processamento empresarial. Seu ecossistema amadureceu durante décadas. Porém, nenhum programa se torna confiável apenas por terminar suas frases com ponto.

COBOL também pode sofrer:

  • S0C7 por dado decimal inválido;

  • S0C4 por referência indevida à memória;

  • S0CB por divisão por zero;

  • falhas de arquivo;

  • erros Db2;

  • deadlocks;

  • timeouts;

  • truncamentos;

  • perda de precisão;

  • loops;

  • commits incorretos;

  • regras de negócio erradas.

O compilador pode aceitar perfeitamente:

       ADD TAXA TO SALDO

Mesmo que a regra correta fosse:

       SUBTRACT TAXA FROM SALDO

Sintaticamente correto.

Financeiramente desastroso.

Clareza também não vem automaticamente

Compare:

       IF X = 'S'
           PERFORM 9000
       END-IF

com:

       IF CLIENTE-ELEGIVEL
           PERFORM CALCULAR-LIMITE
       END-IF

O segundo código apresenta intenção.

Use nomes que revelem o negócio:

  • VALIDAR-LIMITE-DA-CONTA;

  • CALCULAR-JUROS;

  • GRAVAR-OPERACAO-REJEITADA;

  • TRATAR-CONTA-ENCERRADA.

Evite transformar a PROCEDURE DIVISION num mapa desenhado pelo Dr. Loveless depois de três garrafas de bourbon.



19. Passo a passo para ler um programa desconhecido

Passo 1 — Descubra a missão

Leia:

  • PROGRAM-ID;

  • comentários funcionais;

  • nome do membro;

  • JCL que executa o programa;

  • documentação relacionada.

Pergunte: qual problema empresarial ele resolve?

Passo 2 — Mapeie entradas e saídas

Procure:

  • SELECT;

  • FD;

  • READ;

  • WRITE;

  • REWRITE;

  • LINKAGE SECTION;

  • PROCEDURE DIVISION USING;

  • EXEC SQL;

  • EXEC CICS;

  • comandos MQ;

  • CALL.

Desenhe as fronteiras antes de estudar todos os detalhes.

Passo 3 — Ache o fluxo principal

Procure nomes como:

  • MAIN;

  • PRINCIPAL;

  • INICIO;

  • INITIALIZE;

  • PROCESS;

  • TERMINATE;

  • FINALIZAR.

Anote os principais PERFORM.

Passo 4 — Encontre as condições de controle

Procure:

  • níveis 88;

  • flags;

  • FILE STATUS;

  • SQLCODE;

  • RESP;

  • RETURN-CODE;

  • indicadores de fim.

Esses elementos mostram como o programa toma decisões.

Passo 5 — Localize as alterações permanentes

Onde ele:

  • grava arquivo?

  • atualiza Db2?

  • reescreve VSAM?

  • envia mensagem?

  • confirma a transação?

  • realiza rollback?

Esses são os pontos de maior risco.

Passo 6 — Siga o caminho infeliz

Não leia somente o cenário de sucesso.

Pergunte:

  • e se a conta não existir?

  • e se o arquivo não abrir?

  • e se o dado não for numérico?

  • e se houver deadlock?

  • e se a operação chegar duas vezes?

  • e se a resposta se perder depois do commit?

Passo 7 — Confirme o contrato físico

Confira:

  • tamanho dos campos;

  • PIC;

  • USAGE;

  • sinal;

  • casas decimais;

  • alinhamento;

  • copybooks;

  • encoding;

  • definição no sistema externo.

Passo 8 — Só então aprofunde cada parágrafo

Depois de compreender o mapa, siga as rotinas em detalhe.

Ler um programa grande da linha 1 até a linha 20.000 sem criar um mapa é como procurar o Dr. Loveless revistando cada parafuso do trem.



20. Curiosidades escondidas no vagão de bagagens

Curiosidade 1 — A série e o COBOL pertencem à mesma era cultural

COBOL surgiu no final dos anos 1950 e se consolidou nos anos 1960. The Wild Wild West estreou em 1965.

Os dois refletem, de maneiras diferentes, uma era fascinada por organizações, máquinas, automação, espionagem e tecnologia.

Curiosidade 2 — O tema musical também é híbrido

A música de Richard Markowitz combinava elementos de jazz e do faroeste. A série precisava soar simultaneamente clássica e moderna.

COBOL também é uma combinação curiosa:

  • palavras quase naturais;

  • layouts rígidos;

  • representação binária e decimal;

  • regras comerciais;

  • execução em hardware extremamente sofisticado.

Curiosidade 3 — Artemus Gordon usou dezenas de disfarces

Ross Martin transformou o personagem num mestre de caracterização. Em COBOL, REDEFINES permite que uma mesma área seja interpretada de maneiras diferentes.

Não significa que REDEFINES foi inspirado por Artemus. Mas o Easter egg é bom demais para ser desperdiçado.

Curiosidade 4 — O primeiro ano foi em preto e branco

A primeira temporada da série foi filmada em preto e branco; as seguintes passaram para cores.

O fonte COBOL também pode parecer monocromático numa listagem antiga, mas ferramentas modernas oferecem navegação, análise, refatoração assistida, integração com Git e depuração visual.

Curiosidade 5 — O ponto pode ser mais perigoso que o revólver

Em COBOL, o ponto encerra uma sentença e pode terminar escopos implícitos.

Código moderno costuma preferir terminadores explícitos:

       IF CONDICAO
           PERFORM ACAO
       ELSE
           PERFORM OUTRA-ACAO
       END-IF

Use períodos com consciência. Um ponto colocado no local errado pode alterar o fluxo de uma estrutura.

Easter egg número 2

Se encontrar isto:

       88 LOVELESS-ESTA-PRESENTE VALUE 'S'.

não execute:

       SET IGNORAR-FILE-STATUS TO TRUE

O vilão já entrou no programa.



21. O mapa mental definitivo

A versão simples é:

Definir dados → processar → obter resultado

A versão profissional é:

Identificar o programa
        ↓
Estabelecer contratos externos
        ↓
Descrever dados e representações
        ↓
Inicializar o estado
        ↓
Receber ou ler informações
        ↓
Validar estrutura e conteúdo
        ↓
Aplicar regras de negócio
        ↓
Alterar o estado de forma controlada
        ↓
Tratar condições e exceções
        ↓
Confirmar ou desfazer
        ↓
Gerar resultado, auditoria e código de retorno

COBOL não trabalha apenas com valores.

Trabalha com contratos e consequências.

Uma data não é somente PIC 9(8).

Precisamos saber:

  • está em AAAAMMDD?

  • zero significa ausência?

  • a data deve existir no calendário?

  • aceita data futura?

  • qual fuso horário está envolvido?

Um valor não é somente PIC S9(11)V99 COMP-3.

Precisamos saber:

  • qual moeda?

  • qual limite?

  • pode ser negativo?

  • como arredondar?

  • débito e crédito usam o mesmo sinal?

  • um estorno deve inverter ou criar nova operação?

O layout diz como ler os bytes.

A regra de negócio diz o que esses bytes significam.



Epílogo — A noite em que o mainframe não improvisou

James West encontrou o Dr. Loveless no último vagão.

Diante dele havia uma máquina gigantesca, engrenagens, luzes e um cartão perfurado com uma única instrução:

       MOVE WS-SALDO-DO-BANCO
         TO WS-CONTA-DO-LOVELESS.

— Um plano brilhante — disse Loveless. — Em poucos minutos, todo o dinheiro estará em minha conta!

Artemus Gordon examinou o programa.

— Receio que exista um problema, doutor.

— Impossível!

— O senhor não declarou corretamente o campo receptor. Também ignorou o FILE STATUS, não verificou o SQLCODE, não criou controle de duplicidade e tentou atualizar o saldo fora de uma unidade de trabalho.

James West sorriu:

— Além disso, o job terminou com COND CODE 0012.

A trilha de Richard Markowitz acelerou.

Loveless puxou uma alavanca.

O trem começou a tremer.

Igor, escondido atrás da WORKING-STORAGE, gritou:

— Eu avisei que PIC 9(3) não comportava um milhão!

O jovem padawan finalmente compreendeu.

As quatro divisões não representavam quatro pensamentos executados sequencialmente. Eram quatro maneiras de organizar o conhecimento necessário para construir o programa:

  • identidade;

  • ambiente;

  • dados;

  • procedimento.

Mas o verdadeiro “pensamento” do COBOL acontecia na interação entre:

  • registros;

  • estados;

  • condições;

  • regras;

  • operações;

  • códigos de retorno;

  • commits;

  • rollbacks.

COBOL não adivinha.

Não improvisa.

Não olha para 000001250 e conclui que provavelmente significa R$12,50.

Alguém precisa declarar a escala, o sinal, a representação e a regra.

É justamente essa disciplina que continua ensinando algo valioso depois de mais de seis décadas:

Em sistemas críticos, clareza não é enfeite colocado depois que o programa funciona. Clareza faz parte do mecanismo que impede o trem de descarrilar.

James West cuidava da ação.

Artemus Gordon compreendia os disfarces.

O JCL preparava os trilhos.

O z/OS controlava a ferrovia.

E o jovem programador COBOL, agora um pouco menos padawan, finalmente aprendeu a regra fundamental do Oeste Selvagem Digital:

Antes de sacar o WRITE, verifique o FILE STATUS. Antes de atualizar o saldo, conheça o contrato. E, quando o Dr. Loveless oferecer um GO TO para uma rotina que ninguém encontra, peça primeiro o mapa do fluxo.



 

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...