 |
| 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:
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:
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:
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:
abre o arquivo de transações;
abre o arquivo de relatório;
abre o arquivo de rejeições;
lê a primeira transação;
valida contas e valores;
classifica a operação;
soma os totais;
grava o resultado;
lê a próxima;
repete até o fim;
fecha todos os arquivos;
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:
receber o conteúdo;
interpretar cada parte;
identificar informações relevantes;
manter contexto;
produzir um resumo.
O COBOL faz algo conceitualmente parecido com um arquivo sequencial.
Ele:
abre o arquivo;
lê um registro;
interpreta os campos;
aplica regras;
acumula informações;
grava um resultado;
continua até o fim.
A diferença está no objetivo.
A IA pode produzir uma síntese textual.
O COBOL pode produzir:
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:
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.