Translate

Mostrar mensagens com a etiqueta OPEN. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta OPEN. Mostrar todas as mensagens

sábado, 14 de dezembro de 2019

O Mistério do Arquivo que Nunca Pulava uma Linha : Como OPEN, READ, PROCESS, WRITE e CLOSE Mantêm o Mundo Financeiro Funcionando Enquanto a Cidade Dorme

 

Bellacosa Mainframe e o misterio do arquivo que nunca pulava uma linha

☕ Um Café no Bellacosa Mainframe

O Mistério do Arquivo que Nunca Pulava uma Linha

Como OPEN, READ, PROCESS, WRITE e CLOSE Mantêm o Mundo Financeiro Funcionando Enquanto a Cidade Dorme

A chuva caía fina sobre os telhados da cidade.

Lá fora, os últimos ônibus atravessavam avenidas quase vazias. As luzes dos escritórios já tinham sido apagadas, os gerentes haviam ido embora, os clientes dormiam convencidos de que o dinheiro continuava imóvel dentro dos bancos e os relógios avançavam silenciosamente em direção à madrugada.

Mas, no subsolo de um grande centro de processamento, as máquinas continuavam acordadas.

O operador do turno da noite segurava uma caneca de café já frio. Diante dele, telas negras exibiam letras verdes, números de jobs, nomes de datasets e mensagens do JES2. Um processamento importante estava prestes a começar.

Milhões de transações realizadas durante o dia seriam lidas, verificadas, calculadas, separadas e gravadas novamente.

Uma por uma.

Sem atalhos.

Sem improvisações.

Sem saltar registros.

Era o trabalho perfeito para o COBOL.

Naquela noite, um jovem programador chamado Arthur seria apresentado a um dos mecanismos mais antigos, simples e poderosos do mundo corporativo:

o processamento de arquivos sequenciais.

Ele ainda não sabia, mas estava prestes a descobrir que boa parte da economia moderna depende de um ciclo aparentemente humilde:

OPEN
READ
PROCESS
WRITE
CLOSE

Cinco palavras.

Cinco portas.

Cinco etapas que, executadas corretamente, podem processar milhões de registros durante uma única madrugada.


1. O arquivo que guardava tudo em ordem

Arthur observou o analista mais velho abrir um membro no editor ISPF.

— Este é o arquivo de transações do dia — disse o veterano.

Na tela apareciam linhas com tamanhos fixos:

0000000001PIX  000012500CLIENTE000001CLIENTE00098720260729
0000000002TED  000250000CLIENTE000122CLIENTE00145620260729
0000000003BOL  000008990CLIENTE000834EMPRESA00005520260729
0000000004SAQ  000050000CLIENTE000912ATM00000002320260729

Cada linha era um registro.

Cada registro representava uma ocorrência de negócio.

Uma transferência.

Um pagamento.

Um saque.

Uma operação realizada por alguém em algum lugar do país.

Aquelas linhas não estavam espalhadas aleatoriamente. Elas estavam armazenadas uma após a outra, em uma sequência definida.

Esse é o princípio básico de um arquivo sequencial.

Um arquivo sequencial armazena registros consecutivamente. Para chegar ao registro número 500, o programa normalmente precisa passar pelos 499 registros anteriores.

É como ler um romance.

Você começa na primeira página.

Depois lê a segunda.

Depois a terceira.

Não se chega naturalmente à solução do mistério começando pela página 317.

No mundo COBOL, o programa lê um registro, processa aquele conteúdo e segue para o próximo.

REGISTRO 1
REGISTRO 2
REGISTRO 3
REGISTRO 4
...
REGISTRO N

A simplicidade desse modelo é exatamente o que o torna tão eficiente para grandes processamentos em lote.


2. Sequencial não significa ultrapassado

Muitos iniciantes cometem um erro de julgamento.

Ao ouvir a palavra “sequencial”, imaginam algo lento, antigo e inferior a bancos de dados modernos.

Nada poderia estar mais distante da realidade.

Arquivos sequenciais continuam extremamente úteis quando o objetivo é processar praticamente todos os registros de um conjunto de dados.

Imagine uma empresa que precisa calcular a folha de pagamento de 200 mil funcionários.

Ela não quer localizar apenas um funcionário.

Ela quer processar todos.

Nesse caso, ler o arquivo inteiro sequencialmente é uma estratégia lógica e eficiente.

O mesmo vale para:

  • fechamento bancário;

  • cálculo de juros;

  • emissão de faturas;

  • geração de extratos;

  • consolidação contábil;

  • processamento de apólices;

  • cálculo de comissões;

  • envio de informações fiscais;

  • classificação de transações;

  • produção de relatórios gerenciais.

O arquivo sequencial não tenta ser uma solução para tudo.

Ele é uma solução excelente para aquilo que foi criado para fazer:

processar grandes volumes de registros em ordem.


3. A herança das fitas magnéticas

Para entender a força do processamento sequencial, é preciso visitar o passado.

Nas décadas iniciais da computação comercial, muitos dados eram armazenados em fitas magnéticas.

A fita era um meio naturalmente sequencial.

Para acessar um registro localizado no meio dela, era necessário avançar fisicamente pelos dados anteriores.

Algo parecido com uma fita cassete.

Quem viveu a era das fitas de áudio sabe como funcionava.

Para ouvir a quinta música, você precisava avançar a fita até o ponto correto. Não havia um índice eletrônico instantâneo como em um aplicativo moderno.

Os primeiros sistemas corporativos foram construídos respeitando essa característica.

E o COBOL nasceu exatamente nesse ambiente.

Por isso, seu modelo de processamento de arquivos é tão natural:

ABRIR A FITA
LER UM REGISTRO
PROCESSAR
LER O PRÓXIMO
PROCESSAR
CONTINUAR ATÉ O FIM
FECHAR A FITA

Mesmo quando os discos substituíram as fitas em muitos cenários, o modelo continuou útil.

Hoje, o dataset pode estar em disco, em armazenamento virtualizado ou em uma infraestrutura moderna de alta velocidade. Ainda assim, o programa pode tratá-lo como um fluxo ordenado de registros.

A tecnologia física mudou.

A lógica permaneceu.


4. A anatomia de um programa COBOL com arquivo

O veterano apontou para a estrutura do programa.

— Para um arquivo existir dentro do COBOL, você precisa apresentá-lo formalmente ao programa.

Um programa de arquivo sequencial envolve várias divisões e seções importantes.

Normalmente, encontramos:

IDENTIFICATION DIVISION.
ENVIRONMENT DIVISION.
DATA DIVISION.
PROCEDURE DIVISION.

Cada parte possui uma responsabilidade.

IDENTIFICATION DIVISION

Identifica o programa.

IDENTIFICATION DIVISION.
PROGRAM-ID. RELATORIO-FUNCIONARIOS.

Aqui o programa recebe um nome.

Parece apenas burocracia, mas nomes são importantes em ambientes corporativos. Eles ajudam na compilação, catalogação, documentação e manutenção.

ENVIRONMENT DIVISION

Relaciona o programa com o ambiente externo.

É aqui que o arquivo lógico do COBOL é associado a uma identificação externa.

ENVIRONMENT DIVISION.

INPUT-OUTPUT SECTION.
FILE-CONTROL.

    SELECT EMPLOYEE-FILE
        ASSIGN TO EMPFILE
        ORGANIZATION IS SEQUENTIAL
        FILE STATUS IS WS-EMP-STATUS.

Observe os elementos.

SELECT EMPLOYEE-FILE

Define o nome lógico que o programa utilizará.

ASSIGN TO EMPFILE

Relaciona o arquivo COBOL ao nome externo usado pelo ambiente de execução.

Em um job z/OS, esse nome geralmente se conecta a um DD statement do JCL.

ORGANIZATION IS SEQUENTIAL

Declara que o arquivo será tratado sequencialmente.

FILE STATUS IS WS-EMP-STATUS

Define uma variável que receberá o resultado de cada operação realizada sobre o arquivo.

Esse último item é fundamental para programas de produção.


5. O elo entre COBOL e JCL

O COBOL conhece o nome lógico.

O JCL conhece o dataset físico.

Essa ligação ocorre por meio do DDNAME.

No COBOL:

SELECT EMPLOYEE-FILE
    ASSIGN TO EMPFILE.

No JCL:

//EMPFILE  DD DSN=EMPRESA.RH.FUNCIONARIOS,
//            DISP=SHR

O COBOL diz:

“Quero trabalhar com EMPFILE.”

O JCL responde:

“EMPFILE corresponde ao dataset EMPRESA.RH.FUNCIONARIOS.”

Essa separação é extremamente poderosa.

O programa não precisa conhecer o nome físico definitivo do arquivo.

Em desenvolvimento, o mesmo programa pode usar:

DSN=DEV.RH.FUNCIONARIOS

Em homologação:

DSN=HML.RH.FUNCIONARIOS

Em produção:

DSN=PRD.RH.FUNCIONARIOS

O código COBOL permanece o mesmo.

Apenas o JCL muda.

É uma forma antiga e elegante de desacoplamento entre programa e ambiente.

Muito antes de a palavra “configuração externa” virar moda em arquiteturas modernas, o mainframe já fazia isso.


6. A FILE SECTION e o formato do registro

Na DATA DIVISION, o programa descreve como cada registro deve ser interpretado.

DATA DIVISION.

FILE SECTION.

FD  EMPLOYEE-FILE.

01  EMPLOYEE-RECORD.
    05 EMP-ID          PIC 9(5).
    05 EMP-NAME        PIC X(30).
    05 EMP-DEPARTMENT  PIC X(10).
    05 EMP-SALARY      PIC 9(7)V99.

O FD significa File Description.

Ele apresenta as características lógicas do arquivo.

Logo abaixo, temos o layout do registro.

01 EMPLOYEE-RECORD.

Esse grupo representa o registro completo lido do arquivo.

Os campos internos descrevem posições específicas.

05 EMP-ID PIC 9(5).

Número do funcionário com cinco dígitos.

05 EMP-NAME PIC X(30).

Nome com trinta caracteres.

05 EMP-DEPARTMENT PIC X(10).

Departamento com dez caracteres.

05 EMP-SALARY PIC 9(7)V99.

Salário com sete dígitos inteiros e duas casas decimais implícitas.

O V não ocupa uma posição física no arquivo. Ele representa uma vírgula decimal lógica.

Por exemplo, o conteúdo:

000350000

pode representar:

R$ 3.500,00

dependendo da definição do campo.

É importante observar que o arquivo sequencial normalmente não carrega separadores visuais entre campos.

O programa sabe onde cada campo começa e termina graças ao layout.


7. Um registro é uma fotografia do negócio

Cada registro pode ser visto como uma pequena fotografia de um evento corporativo.

Em uma folha de pagamento:

FUNCIONÁRIO
SALÁRIO
DEPARTAMENTO
HORAS EXTRAS
DESCONTOS

Em uma transação bancária:

CONTA
AGÊNCIA
VALOR
TIPO DE OPERAÇÃO
DATA

Em um sistema de seguros:

APÓLICE
CLIENTE
PRÊMIO
COBERTURA
VIGÊNCIA

O COBOL lê essa fotografia e interpreta cada pedaço segundo as regras do layout.

Se o layout estiver errado, a interpretação estará errada.

Um campo de valor pode ser lido como data.

Um nome pode invadir o campo de departamento.

Um código pode ficar deslocado.

Por isso, conhecer o layout do arquivo é uma das tarefas mais importantes para qualquer programador COBOL.

Em muitos incidentes de produção, o programa está tecnicamente correto.

O problema é que o arquivo recebido não respeita o layout esperado.


8. OPEN: a porta do arquivo

Nenhuma operação pode começar antes do OPEN.

OPEN INPUT EMPLOYEE-FILE

O OPEN prepara o arquivo para uso.

Ele informa ao ambiente de execução qual será o tipo de acesso.

Existem quatro modos principais.

OPEN INPUT

Usado para leitura.

OPEN INPUT EMPLOYEE-FILE

Operações típicas:

READ EMPLOYEE-FILE

O programa não pode gravar nesse arquivo.

OPEN OUTPUT

Usado para criar ou preparar um arquivo de saída.

OPEN OUTPUT REPORT-FILE

Depois, o programa pode executar:

WRITE REPORT-RECORD

É preciso atenção.

Em muitos cenários, abrir um arquivo como OUTPUT significa iniciar um novo conteúdo. O arquivo anterior pode ser substituído conforme a configuração do ambiente.

OPEN EXTEND

Usado para acrescentar registros ao final de um arquivo existente.

OPEN EXTEND LOG-FILE

É útil para arquivos de log ou históricos acumulativos.

OPEN I-O

Usado quando o programa precisa ler e atualizar o arquivo.

OPEN I-O CUSTOMER-FILE

Esse modo é mais comum em arquivos que suportam atualização apropriada, como certos cenários com VSAM.

Em arquivos sequenciais tradicionais, atualizações no meio do arquivo exigem estratégias específicas e frequentemente envolvem a geração de um novo arquivo.


9. O FILE STATUS: o informante que nunca deve ser ignorado

O veterano aproximou a cadeira.

— Programador iniciante acredita que um OPEN sempre funciona. Programador experiente pergunta o que aconteceu depois do OPEN.

Para isso existe o FILE STATUS.

01 WS-EMP-STATUS PIC XX.

Após uma operação:

OPEN INPUT EMPLOYEE-FILE

o programa verifica:

IF WS-EMP-STATUS NOT = '00'
    DISPLAY 'ERRO NO OPEN: ' WS-EMP-STATUS
    STOP RUN
END-IF

O código "00" normalmente indica sucesso.

Outros códigos podem indicar situações como:

  • arquivo inexistente;

  • modo de acesso incorreto;

  • fim do arquivo;

  • registro duplicado;

  • arquivo não aberto;

  • erro lógico ou físico.

O FILE STATUS é uma testemunha silenciosa.

Ele não impede o erro.

Mas informa exatamente que algo não saiu como esperado.

Ignorá-lo é como investigar um crime e desprezar a única pessoa que viu o suspeito.


10. READ: um registro de cada vez

Após abrir o arquivo, o programa começa a leitura.

READ EMPLOYEE-FILE

Cada READ transfere um registro do arquivo para a área definida na FILE SECTION.

O programa não recebe o arquivo inteiro.

Recebe apenas o registro atual.

Exemplo:

Arquivo:

00001ARTHUR COSTA                  TI        000750000
00002MARIA SILVA                   RH        000620000
00003JOAO PEREIRA                  FIN       000810000

Primeiro READ:

EMP-ID         = 00001
EMP-NAME       = ARTHUR COSTA
EMP-DEPARTMENT = TI
EMP-SALARY     = 000750000

Segundo READ:

EMP-ID         = 00002
EMP-NAME       = MARIA SILVA
EMP-DEPARTMENT = RH
EMP-SALARY     = 000620000

Cada leitura substitui o conteúdo anterior da área do registro.

Se o programa precisa preservar dados de registros anteriores, deve movê-los para variáveis de trabalho ou acumuladores.


11. O fim do arquivo: AT END

Todo arquivo termina.

O programa precisa saber quando não existem mais registros.

READ EMPLOYEE-FILE
    AT END
        MOVE 'Y' TO WS-END-OF-FILE
END-READ

Uma flag simples pode controlar todo o loop.

01 WS-END-OF-FILE PIC X VALUE 'N'.

Enquanto o valor for "N", ainda existem registros a processar.

Quando se torna "Y", a leitura terminou.

Uma abordagem tradicional é:

PERFORM UNTIL WS-END-OF-FILE = 'Y'
    READ EMPLOYEE-FILE
        AT END
            MOVE 'Y' TO WS-END-OF-FILE
        NOT AT END
            PERFORM PROCESS-EMPLOYEE
    END-READ
END-PERFORM

Essa estrutura é clara e segura.

O processamento ocorre apenas quando o READ realmente encontrou um registro.


12. A leitura antecipada

Existe outra técnica muito comum em COBOL batch.

Ela é chamada informalmente de priming read, ou leitura inicial.

O programa faz uma leitura antes do loop.

PERFORM READ-EMPLOYEE

PERFORM UNTIL WS-END-OF-FILE = 'Y'
    PERFORM PROCESS-EMPLOYEE
    PERFORM READ-EMPLOYEE
END-PERFORM

O parágrafo de leitura:

READ-EMPLOYEE.

    READ EMPLOYEE-FILE
        AT END
            MOVE 'Y' TO WS-END-OF-FILE
        NOT AT END
            ADD 1 TO WS-READ-COUNT
    END-READ.

Essa abordagem separa melhor as responsabilidades.

O loop principal fica fácil de entender:

LER O PRIMEIRO
ENQUANTO NÃO TERMINAR
    PROCESSAR
    LER O PRÓXIMO
FIM

É um padrão extremamente comum em programas COBOL tradicionais.


13. PROCESS: onde mora a inteligência do negócio

O arquivo apenas fornece dados.

O parágrafo de processamento decide o que fazer com eles.

PROCESS-EMPLOYEE.

    IF EMP-SALARY > 000700000
        ADD 1 TO WS-HIGH-SALARY-COUNT
    END-IF.

Mas programas reais fazem muito mais.

Podem:

  • calcular impostos;

  • verificar faixas salariais;

  • aplicar juros;

  • classificar clientes;

  • validar códigos;

  • detectar inconsistências;

  • acumular totais;

  • produzir registros de erro;

  • decidir qual arquivo receberá o registro;

  • montar linhas de relatório.

Exemplo de cálculo de bônus:

IF EMP-DEPARTMENT = 'VENDAS'
    COMPUTE WS-BONUS = EMP-SALARY * 0.10
ELSE
    COMPUTE WS-BONUS = EMP-SALARY * 0.05
END-IF

Suponha um salário de:

R$ 5.000,00

Para o departamento de vendas:

Bônus = R$ 500,00

Para outro departamento:

Bônus = R$ 250,00

O COBOL é particularmente forte nesse tipo de regra clara, determinística e repetitiva.


14. Acumuladores e contadores

Programas de arquivo sequencial quase sempre utilizam contadores e acumuladores.

Contador de registros lidos

ADD 1 TO WS-READ-COUNT

Contador de registros gravados

ADD 1 TO WS-WRITE-COUNT

Acumulador de valores

ADD EMP-SALARY TO WS-TOTAL-SALARY

No final, o programa pode exibir:

REGISTROS LIDOS    : 00000200
REGISTROS GRAVADOS : 00000198
REGISTROS REJEITADOS: 00000002
TOTAL DE SALÁRIOS  : R$ 945.300,00

Esses totais são importantes para reconciliação.

Se foram lidos 200 registros, mas apenas 198 foram gravados, os outros dois precisam estar explicados.

Talvez tenham sido rejeitados.

Talvez tenham sido enviados para um arquivo de erros.

Talvez exista um defeito.

Em produção, números de controle são pistas essenciais.


15. WRITE: transformando processamento em resultado

Depois de processar um registro, o programa pode gravar uma saída.

WRITE REPORT-RECORD

Antes do WRITE, normalmente o programa monta o registro de saída.

MOVE EMP-ID         TO OUT-EMP-ID
MOVE EMP-NAME       TO OUT-EMP-NAME
MOVE EMP-SALARY     TO OUT-EMP-SALARY
MOVE WS-BONUS       TO OUT-BONUS

WRITE REPORT-RECORD

O arquivo de saída pode ter um layout diferente do arquivo de entrada.

Entrada:

ID
NOME
DEPARTAMENTO
SALÁRIO

Saída:

ID
NOME
SALÁRIO
BÔNUS
SALÁRIO FINAL

Esse é um dos padrões mais clássicos do batch:

ARQUIVO DE ENTRADA
        ↓
   PROGRAMA COBOL
        ↓
ARQUIVO DE SAÍDA

O programa atua como uma máquina de transformação.


16. Arquivos de rejeição

Programas robustos não encerram necessariamente por causa de um único registro inválido.

Em muitos casos, o registro problemático é enviado para um arquivo separado.

IF EMP-ID IS NOT NUMERIC
    MOVE EMPLOYEE-RECORD TO REJECT-RECORD
    WRITE REJECT-RECORD
    ADD 1 TO WS-REJECT-COUNT
ELSE
    PERFORM PROCESS-VALID-EMPLOYEE
END-IF

Assim, o processamento principal continua.

No final, uma equipe pode analisar os registros rejeitados.

Esse desenho é comum em integrações de grande volume.

Um arquivo com um milhão de registros não deve necessariamente ser descartado inteiro porque três linhas estão incorretas.

Tudo depende da regra de negócio e do nível de criticidade.


17. CLOSE: o último ato do caso

Depois do último registro, os arquivos precisam ser fechados.

CLOSE EMPLOYEE-FILE
      REPORT-FILE
      REJECT-FILE

O CLOSE faz mais do que encerrar formalmente o uso.

Ele permite que o sistema:

  • descarregue buffers pendentes;

  • finalize gravações;

  • libere recursos;

  • complete operações de entrada e saída;

  • mantenha a consistência do arquivo.

Um programa disciplinado abre, usa e fecha corretamente seus arquivos.

O CLOSE é o momento em que o detetive guarda as provas, fecha o armário e registra oficialmente o fim da investigação.


18. Um programa completo comentado

A seguir, um exemplo didático.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. EMPREPORT.

       ENVIRONMENT DIVISION.

       INPUT-OUTPUT SECTION.
       FILE-CONTROL.

           SELECT EMPLOYEE-FILE
               ASSIGN TO EMPFILE
               ORGANIZATION IS SEQUENTIAL
               FILE STATUS IS WS-EMP-STATUS.

           SELECT REPORT-FILE
               ASSIGN TO REPORT
               ORGANIZATION IS SEQUENTIAL
               FILE STATUS IS WS-REP-STATUS.

       DATA DIVISION.

       FILE SECTION.

       FD  EMPLOYEE-FILE.

       01  EMPLOYEE-RECORD.
           05 EMP-ID              PIC 9(5).
           05 EMP-NAME            PIC X(30).
           05 EMP-DEPARTMENT      PIC X(10).
           05 EMP-SALARY          PIC 9(7)V99.

       FD  REPORT-FILE.

       01  REPORT-RECORD.
           05 OUT-EMP-ID          PIC 9(5).
           05 FILLER              PIC X VALUE SPACE.
           05 OUT-EMP-NAME        PIC X(30).
           05 FILLER              PIC X VALUE SPACE.
           05 OUT-BONUS           PIC 9(7)V99.

       WORKING-STORAGE SECTION.

       01  WS-END-OF-FILE         PIC X VALUE 'N'.
           88 END-OF-FILE         VALUE 'Y'.
           88 NOT-END-OF-FILE     VALUE 'N'.

       01  WS-EMP-STATUS          PIC XX.
       01  WS-REP-STATUS          PIC XX.

       01  WS-BONUS               PIC 9(7)V99 VALUE ZERO.

       01  WS-COUNTERS.
           05 WS-READ-COUNT       PIC 9(9) VALUE ZERO.
           05 WS-WRITE-COUNT      PIC 9(9) VALUE ZERO.

       PROCEDURE DIVISION.

       MAIN-PROCESS.

           PERFORM OPEN-FILES

           IF WS-EMP-STATUS = '00'
              AND WS-REP-STATUS = '00'

               PERFORM READ-EMPLOYEE

               PERFORM UNTIL END-OF-FILE
                   PERFORM PROCESS-EMPLOYEE
                   PERFORM WRITE-REPORT
                   PERFORM READ-EMPLOYEE
               END-PERFORM

           END-IF

           PERFORM CLOSE-FILES
           PERFORM DISPLAY-TOTALS

           STOP RUN.

       OPEN-FILES.

           OPEN INPUT  EMPLOYEE-FILE
                OUTPUT REPORT-FILE

           IF WS-EMP-STATUS NOT = '00'
               DISPLAY 'ERRO OPEN EMPFILE: ' WS-EMP-STATUS
           END-IF

           IF WS-REP-STATUS NOT = '00'
               DISPLAY 'ERRO OPEN REPORT: ' WS-REP-STATUS
           END-IF.

       READ-EMPLOYEE.

           READ EMPLOYEE-FILE
               AT END
                   SET END-OF-FILE TO TRUE
               NOT AT END
                   ADD 1 TO WS-READ-COUNT
           END-READ.

       PROCESS-EMPLOYEE.

           IF EMP-DEPARTMENT = 'VENDAS'
               COMPUTE WS-BONUS = EMP-SALARY * 0.10
           ELSE
               COMPUTE WS-BONUS = EMP-SALARY * 0.05
           END-IF.

       WRITE-REPORT.

           INITIALIZE REPORT-RECORD

           MOVE EMP-ID     TO OUT-EMP-ID
           MOVE EMP-NAME   TO OUT-EMP-NAME
           MOVE WS-BONUS   TO OUT-BONUS

           WRITE REPORT-RECORD

           IF WS-REP-STATUS = '00'
               ADD 1 TO WS-WRITE-COUNT
           ELSE
               DISPLAY 'ERRO WRITE REPORT: ' WS-REP-STATUS
           END-IF.

       CLOSE-FILES.

           CLOSE EMPLOYEE-FILE
                 REPORT-FILE.

       DISPLAY-TOTALS.

           DISPLAY 'REGISTROS LIDOS   : ' WS-READ-COUNT
           DISPLAY 'REGISTROS GRAVADOS: ' WS-WRITE-COUNT.

Esse programa ilustra os principais conceitos:

  • definição do arquivo;

  • associação externa;

  • layout do registro;

  • FILE STATUS;

  • abertura;

  • leitura;

  • detecção de fim;

  • processamento;

  • gravação;

  • fechamento;

  • contagem de registros.


19. O fluxo mental que o iniciante deve dominar

Antes de escrever qualquer código, desenhe o fluxo.

INÍCIO
  |
ABRIR ARQUIVOS
  |
OPEN FUNCIONOU?
  |
  +-- NÃO → INFORMAR ERRO E ENCERRAR
  |
  +-- SIM
        |
      LER PRIMEIRO REGISTRO
        |
      FIM DO ARQUIVO?
        |
        +-- SIM → FECHAR ARQUIVOS
        |
        +-- NÃO
              |
           VALIDAR
              |
           PROCESSAR
              |
           GRAVAR
              |
           LER PRÓXIMO
              |
           VOLTAR AO TESTE

Se esse fluxo estiver claro, o código será apenas a tradução da lógica.

O erro mais comum é começar pela sintaxe sem entender o ciclo.

O COBOL não é difícil porque possui palavras em inglês.

Ele se torna difícil quando o programador não sabe qual é o estado do arquivo em cada momento.

Pergunte sempre:

  • o arquivo já foi aberto?

  • o registro atual é válido?

  • o fim do arquivo já foi atingido?

  • a gravação funcionou?

  • os arquivos foram fechados?

  • quantos registros foram lidos?

  • quantos foram gravados?

  • houve rejeições?


20. Arquivo sequencial fixo e variável

Nem todo arquivo sequencial possui registros do mesmo tamanho.

No z/OS, dois formatos muito conhecidos são:

FB — Fixed Blocked

Registros de tamanho fixo.

Exemplo:

LRECL=80

Cada registro possui exatamente 80 bytes.

Se um nome ocupa apenas 20 posições de um campo de 30, as posições restantes normalmente são preenchidas com espaços.

VB — Variable Blocked

Registros de tamanho variável.

Cada registro pode possuir um tamanho diferente, dentro dos limites definidos.

Programadores iniciantes costumam trabalhar primeiro com arquivos fixos porque o layout é mais direto.

Ao receber um arquivo, procure conhecer:

  • RECFM;

  • LRECL;

  • BLKSIZE;

  • codificação;

  • layout;

  • quantidade esperada de registros;

  • origem;

  • destino;

  • critérios de validação.

Um programa pode compilar perfeitamente e ainda assim falhar porque o LRECL não corresponde ao layout.


21. O truque dos buffers

Quando o COBOL executa:

READ EMPLOYEE-FILE

parece que o sistema busca fisicamente apenas aquele registro.

Na prática, o sistema pode usar buffers.

Um bloco contendo vários registros é lido para a memória.

O programa recebe um registro por vez, mas o sistema reduz a quantidade de acessos físicos ao dispositivo.

Esse mecanismo melhora muito o desempenho.

Imagine um arquivo com um milhão de registros.

Buscar cada registro individualmente no dispositivo seria caro.

Ler blocos maiores e entregar os registros gradualmente é muito mais eficiente.

Esse detalhe é quase invisível para o programador, mas explica parte da enorme capacidade de throughput dos ambientes mainframe.


22. Sequencial versus VSAM KSDS

Arthur fez a pergunta inevitável:

— E se eu quiser buscar apenas o funcionário 54321?

O veterano sorriu.

— Então talvez você não queira um arquivo sequencial.

Em um arquivo sequencial, para encontrar um registro localizado no meio do arquivo, o programa normalmente precisa ler os anteriores.

Já um VSAM KSDS utiliza uma chave e uma estrutura indexada.

Pode localizar diretamente um registro específico.

Arquivo sequencial

Ideal para:

  • processamento completo;

  • relatórios;

  • interfaces;

  • cargas;

  • extrações;

  • ordenações;

  • consolidações batch.

VSAM KSDS

Ideal para:

  • acesso por chave;

  • consultas online;

  • atualizações de registros específicos;

  • aplicações CICS;

  • recuperação rápida de dados individuais.

A escolha depende da necessidade.

Não existe tecnologia universalmente superior.

Existe arquitetura adequada ao problema.


23. Erros clássicos de iniciantes

Processar depois do fim do arquivo

Erro:

READ EMPLOYEE-FILE
PERFORM PROCESS-EMPLOYEE

Se o READ encontrou o fim do arquivo, o programa pode processar dados antigos que ainda estão na área do registro.

Forma segura:

READ EMPLOYEE-FILE
    AT END
        SET END-OF-FILE TO TRUE
    NOT AT END
        PERFORM PROCESS-EMPLOYEE
END-READ

Não verificar o OPEN

O programa tenta ler um arquivo que não foi aberto corretamente.

Abrir em modo errado

Abrir como INPUT e tentar gravar.

Esquecer de inicializar o registro de saída

Campos podem carregar conteúdo da gravação anterior.

INITIALIZE REPORT-RECORD

pode ajudar, desde que usado conscientemente.

Não validar campos numéricos

Um campo definido como numérico pode receber conteúdo inválido do arquivo externo.

Antes de calcular:

IF EMP-SALARY IS NUMERIC
    CONTINUE
ELSE
    PERFORM REJECT-RECORD
END-IF

Ignorar contadores

Sem total de entrada e saída, a reconciliação fica muito mais difícil.

Misturar tudo no mesmo parágrafo

Programas tornam-se confusos quando OPEN, READ, cálculo, WRITE e CLOSE são escritos em um único bloco gigantesco.

Separar responsabilidades facilita testes e manutenção.


24. Dicas de sobrevivência no turno da madrugada

Dica 1 — Sempre conheça o layout

Não programe com base em suposições.

Dica 2 — Use FILE STATUS

Especialmente em OPEN, READ e WRITE.

Dica 3 — Conte tudo

Registros lidos, processados, gravados e rejeitados.

Dica 4 — Separe leitura, processamento e escrita

Parágrafos pequenos são mais fáceis de analisar.

Dica 5 — Preserve o registro original quando necessário

Antes de alterar campos de entrada:

MOVE EMPLOYEE-RECORD TO WS-ORIGINAL-RECORD

Dica 6 — Planeje o tratamento de arquivo vazio

Um arquivo vazio pode ser perfeitamente válido.

O primeiro READ retornará fim do arquivo.

Dica 7 — Diferencie erro técnico de erro de negócio

Arquivo inexistente é erro técnico.

Salário negativo pode ser erro de negócio.

Eles exigem tratamentos diferentes.

Dica 8 — Registre mensagens úteis

Evite:

DEU ERRO

Prefira:

ERRO AO ABRIR EMPFILE. FILE STATUS: 35

Quanto melhor a mensagem, menor o tempo de investigação.


25. O exemplo do fechamento bancário

Imagine um banco realizando o fechamento do dia.

Arquivo de entrada:

TRANSACTIONS.DAT

Cada registro contém:

NÚMERO DA TRANSAÇÃO
TIPO
CONTA DE ORIGEM
CONTA DE DESTINO
VALOR
DATA
HORÁRIO

O programa executa:

  1. abre o arquivo de transações;

  2. abre o arquivo de relatório;

  3. abre o arquivo de rejeições;

  4. lê a primeira transação;

  5. valida contas e valores;

  6. classifica a operação;

  7. soma os totais;

  8. grava o resultado;

  9. lê a próxima;

  10. repete até o fim;

  11. fecha todos os arquivos;

  12. mostra os totais de controle.

Ao final:

TRANSAÇÕES LIDAS      : 12.500.000
TRANSAÇÕES PROCESSADAS: 12.499.982
TRANSAÇÕES REJEITADAS : 18
TOTAL PIX             : R$ 987.500.320,18
TOTAL TED             : R$ 145.830.000,00
TOTAL BOLETOS         : R$ 82.114.942,11

Esses números não são apenas informativos.

Eles ajudam a provar que o processamento foi completo e coerente.


26. A analogia com Inteligência Artificial

A comparação com uma IA lendo um documento é interessante.

Imagine um documento com 500 páginas.

A IA precisa:

  1. receber o conteúdo;

  2. interpretar cada parte;

  3. identificar informações relevantes;

  4. manter contexto;

  5. produzir um resumo.

O COBOL faz algo conceitualmente parecido com um arquivo sequencial.

Ele:

  1. abre o arquivo;

  2. lê um registro;

  3. interpreta os campos;

  4. aplica regras;

  5. acumula informações;

  6. grava um resultado;

  7. continua até o fim.

A diferença está no objetivo.

A IA pode produzir uma síntese textual.

O COBOL pode produzir:

  • uma folha de pagamento;

  • um extrato;

  • uma posição contábil;

  • um arquivo fiscal;

  • uma fatura;

  • uma lista de clientes;

  • uma interface para outro sistema.

Nos dois casos, existe um fluxo de entrada, interpretação e saída.


27. Curiosidades do mundo sequencial

A simplicidade é uma vantagem

Sistemas sequenciais possuem poucos estados e um fluxo previsível. Isso facilita auditoria e repetição.

Um arquivo pode alimentar vários programas

Um programa gera o arquivo A.

Outro programa lê A e produz B.

Um terceiro lê B e atualiza um banco de dados.

Essa cadeia forma um fluxo batch.

Arquivos podem ser checkpoints naturais

Em alguns processos, cada etapa gera uma saída persistente. Se a etapa seguinte falhar, não é necessário repetir tudo desde o começo.

SORT é companheiro frequente do COBOL

Muitos arquivos precisam ser classificados antes do processamento.

Um utilitário SORT pode ordenar por conta, data, agência ou código antes de entregar os dados ao programa COBOL.

O conteúdo pode viajar entre plataformas

Arquivos gerados no mainframe podem alimentar sistemas distribuídos, ambientes de analytics, data lakes e APIs.

O conceito é antigo.

A integração continua moderna.


28. Perguntas de entrevista

O que é um arquivo sequencial?

É um arquivo no qual os registros são armazenados e normalmente acessados em ordem, um após o outro.

Quais são as operações básicas?

OPEN
READ
PROCESS
WRITE
CLOSE

Como o programa identifica o fim do arquivo?

Por meio da cláusula AT END, do FILE STATUS ou de ambos, conforme a implementação.

Qual a diferença entre INPUT e OUTPUT?

INPUT abre para leitura.

OUTPUT abre para gravação de um novo conteúdo.

Para que serve EXTEND?

Para acrescentar novos registros ao final de um arquivo.

Por que usar FILE STATUS?

Para verificar o resultado de operações realizadas no arquivo.

O que é um FD?

É a descrição do arquivo na FILE SECTION.

Onde o arquivo físico é definido no z/OS?

Normalmente no JCL, por meio de um DD statement relacionado ao nome usado em ASSIGN TO.

Um arquivo sequencial é adequado para consulta direta por chave?

Geralmente não. Para acesso direto por chave, um formato indexado como VSAM KSDS pode ser mais apropriado.


29. Easter egg: o registro número 1959

Arthur passou horas testando o programa.

Ao final, o arquivo de entrada continha exatamente 1.959 registros.

O número chamou sua atenção.

— Por que 1959? — perguntou.

O veterano olhou para a tela e respondeu:

— Foi o ano em que o CODASYL começou a organizar as bases daquilo que se tornaria o COBOL.

Arthur abriu o último registro.

No campo de observação havia uma mensagem estranha:

READ THE RECORD. TRUST THE STATUS.

Ele riu.

Parecia uma brincadeira deixada por algum programador décadas antes.

Mas o veterano não riu.

— Nunca ignore uma mensagem antiga em produção.

Arthur verificou o FILE STATUS.

10

Fim de arquivo.

Tudo normal.

Ele fechou o dataset e pensou que o mistério havia terminado.

Foi então que percebeu um detalhe.

O contador mostrava:

REGISTROS LIDOS: 000001958

Faltava um.

O programa havia encerrado o loop antes de processar o último registro.

O erro estava na posição da leitura.

A condição de fim era testada no momento errado.

Arthur corrigiu a lógica:

PERFORM READ-EMPLOYEE

PERFORM UNTIL END-OF-FILE
    PERFORM PROCESS-EMPLOYEE
    PERFORM READ-EMPLOYEE
END-PERFORM

Executou novamente.

REGISTROS LIDOS: 000001959

Agora tudo estava certo.

O último registro havia sido processado.

O veterano tomou um gole de café e finalmente sorriu.

— O arquivo nunca mente. O loop, às vezes, sim.


30. O ensinamento final

O processamento sequencial pode parecer simples.

E realmente é.

Mas simplicidade não significa falta de profundidade.

Para dominar arquivos sequenciais, o programador precisa compreender:

  • organização dos dados;

  • layout de registros;

  • relação entre COBOL e JCL;

  • modos de abertura;

  • leitura segura;

  • fim de arquivo;

  • regras de negócio;

  • gravação;

  • FILE STATUS;

  • contadores;

  • rejeições;

  • reconciliação;

  • desempenho;

  • fechamento correto.

Esses princípios aparecem em incontáveis aplicações corporativas.

Quando um banco fecha o movimento do dia, um arquivo sequencial pode estar envolvido.

Quando uma seguradora recalcula milhares de apólices, um arquivo sequencial pode estar envolvido.

Quando o governo processa benefícios, impostos ou registros administrativos, um arquivo sequencial pode estar envolvido.

Quando uma empresa gera a folha de pagamento, novamente ele pode estar lá.

Silencioso.

Disciplinado.

Registro por registro.


Epílogo — O último CLOSE

Já passava das quatro da manhã.

O job terminou com sucesso.

MAXCC=0000

Os arquivos de saída estavam completos.

Os totais conferiam.

Nenhuma transação havia sido perdida.

Arthur fechou o editor, mas permaneceu alguns segundos olhando para a tela.

Agora entendia que o COBOL não era apenas uma linguagem antiga cercada por terminais verdes e histórias de veteranos.

Era uma ferramenta construída para tratar dados com ordem, previsibilidade e responsabilidade.

Antes de ir embora, ele escreveu em seu caderno:

OPEN  — abra a porta com cuidado.
READ  — examine uma evidência por vez.
PROCESS — aplique a lógica sem preconceitos.
WRITE — registre aquilo que foi descoberto.
CLOSE — encerre o caso corretamente.

Do lado de fora, a chuva havia parado.

A cidade começava a acordar.

Milhões de pessoas abririam aplicativos, consultariam saldos, receberiam pagamentos e examinariam extratos sem imaginar que, durante a madrugada, um programa COBOL havia percorrido silenciosamente um enorme arquivo.

Uma linha após a outra.

Um registro após o outro.

Até o fim.

E, como todo bom detetive das antigas, o programa só abandonou o local depois de executar o comando final:

CLOSE EMPLOYEE-FILE
      REPORT-FILE.

STOP RUN.

Caso encerrado.

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