Capitulo 5 - Cobol
Common Business Oriented Language foi desenhada lá por volta de 1960 vamos falar especificamente sobre o COBOL que roda no mainframe, no momento da escrita desse texto (2018), a IBM esta com a versão V6.2 que engloba muitas melhorias de performance e uso de CPU mas tambem insere novos tratamentos de dados deixando o COBOL mais amigavel com as novas linguages e o mundo cloud.
Todo e qualquer programa COBOL tem a mesma estrutura, a linguagem divide os programas em pedaços, são 4 grandes áreas.
A primeira a Identification Division que atualmente contém apenas 2 linhas, é aqui que fica o nome do programa.
123456789012345678901234567890 ID DIVISION. PROGRAM-ID. BUGA#001.
A próxima é a Environment Division que basicamente vai conter um “DECIMAL-POINT IS COMMA” na Special Names dentro da Configuration section, se usar orientação a objetos aqui o bicho pega mas não é o escopo desse texto, sem falar que nunca nem vi.
12345678901234567890123456789012345678901234567890 ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. DECIMAL POINT IS COMMA.
Se o programa utilizar arquivos (geralmente) eles serão definidos na Input-Output section, existem exceções quando se utiliza algum monitor on-line ou alocação dinamica via algum utilitário existente na instalação. Enfim, seria algo como
123456789012345678901234567890 INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT ENTRADA ASSIGN TO ENTRADA FILE STATUS IS STATUS-ENTRADA.
Na sequencia vem a Data Division, que se tiver arquivos no programa conterá a File Section com as caracteristicas dos arquivos. Normalmente tem a Working-Storage, a Local-Storage e a Linkage Section que contém todas as variáveis que serão utilzadas pelo programa (e geralmente um monte de variável orfã que veio do control+c do programa original e que ninguem se atentou em retira-las do programa).
Finalizamos as divisoes do Cobol com a Procedure Division que é onde será estruturado seu programa, é onde a mágica acontece!
Resumindo:
Identification Division – identificação do programa, nome do módulo Environment Division – Especificidades do sistema e arquivos acessados Data Division – definicao de variaveis Procedure Division – programação propriamente dita
O Cobol tem rigidez de formato até hoje (2018).
As colunas de 1 a 6 atualmente não tem função as de 73 a 80 também (dependendo da instalação o pessoal costuma usar essas areas para indentificar os locais onde a alteração esta sendo realizada ou identificando as novas linhas). A coluna 7 aceita ‘*’ para comentar a linha, ‘/’ para quebrar pagina na listagem, ‘D’ para indicar que é uma linha a ser executada apenas quando o debug mode estiver ativo e ‘-’ para indicar que o comando esta continuando nessa linha. As colunas de 8 a 11, vulgo area A, é onde pode começar as sections, divisions e definições de variaveis de niveis elementares. Da coluna 12 até a 72 são a area para os comandos, se não couber pode continuar na linha seguinte.
Organização de um programa Cobol
Se você for trabalhar em fabrica de software provavelmente receberá um manual com as regras e boas praticas do cliente, tente segui-lo para evitar dores de cabeça. Caso encontre algo que possa ser melhorado ou alguma coisa que não tem fundamento - algo do tipo, porque usam isso ? - indage, sugira e tente sempre inovar e mudar o status de “sempre foi assim”.
Pode ser que te enviem uma especificação em “papel de pão” ou uma toda bonitinha em pseudo-código, seja como for, tente fazer o máximo possivel sem ajuda e quando encontrar um ponto que não consiga mais avançar, peça ajuda, às vezes é uma movimentação de X’32’ pra uma variavel XPTO que todo mundo faz automaticamente e que simplesmente esqueceram de documentar que precisa dela ou mesmo o que o x’32’ significa. Não vá brigar com o analista porque ele esqueceu de especificar algum comando que pra ele parecia básico, por vezes deve ser basico mesmo, converse e explique que no momento você precisa de algo mais detalhado.
Programas Legados
Via de regra não tem mais organização bem definida, possui variaveis não referenciadas, mais de 5 mil linhas, um monte de book (seja de variáveis ou mesmo de código), código morto (pedações de código que nunca serão executados), linhas de código antigo comentadas que não servem mais pra nada, enfim, é um excelente desafio! Existem basicamente apenas 2 maneiras de encarar um programa legado e infelizmente depende muito do shop que você estiver trabalhando. Podem pedir para dar aquela repaginada no programa (code refactoring) ou simplesmente podem pedir pra você ignorar tudo que tem lá, fazer sua alteração, testar seu pedaço e bola pra frente. Caso você possa pegar um código legado e dar uma bela ajustada nele garanto que será uma das melhores maneiras de aprender a programar Cobol.
Variáveis Não tem segredo, ou é numero ou é uma string! Ah, mas eu li que tem variavel booleana, ponto flutuante, tabela, decimal… tá, até tem, mas é muito mais simples que isso, vai por mim que não tem tempo ruim… ou é numero ou é uma string (texto).
Existe uma especificidade na declaração de variaveis no Cobol, além do local dentro do programa, tem uma hierarquia de niveis, tipos, tamanhos, declarações, valores de inicialização, redefinições e mais alguma coisa maluca que por ventura você venha a deparar.
Com um pouco de tempo, analisando códigos, resolvendo problemas e lendo os manuais, você conseguirá entender todas as nuances de como trabalhar com variáveis, não tenha pressa, existem definições que são raramente utilizadas e quando você topar com alguma que nunca tenha visto, dispense um tempinho pra entender como esta sendo utilizada na logica do programa e se pelo contexto não conseguir chegar num entendimento, converse com seu coleguinha, procure no google (as vezes tem alguém que começou a trabalhar com mainframe depois de 2010 e que pode ter colocado alguma coisa na internet), ou recorra ao manual.
Tenha sempre cuidado com a movimentação de variaveis e calculos com elas pois o Cobol deixa você fazer quase tudo que quiser mesmo que sua variavel seja “incompativel” com a operação solicitada.
Deixa eu exemplificar:
se você tem uma variavel numerica de 4 posicoes contendo 1234 e movimenta ela para outra numerica mas que só tem 3 posicoes de tamanho, a variavel que recebe o dado conterá 234.
Um contador numérico, digamos que ele tenha 2 posicoes, que vai de 00 até 99, ao adicionar mais 1 e ele tiver no 99 dependedo dos padroes da sua instalação pode ser que nem erro dê! Vai pra 00 de novo. Se der, não tenha preguiça utilize o ON SIZE ERROR, vai evitar muita dor de cabeça.
Declaracoes de variaveis numericas com virgula são outro ponto de atenção, lembro uma vez que um colega nosso, acho que foi o Fabricio que fez a peripécia de ao invés de mandar 20 reais mandou 2000, isso por causa do V99 que tinha na declaração do numero! Segue mais um exemplo agora em Coboles mesmo, movimentar de PIC 9(6)v99 para um PIC 9(2)V9999 pode dar problema, se tiver 123456,78 e você mover vai ficar com 56,7800. Sempre preste atenção nas movimentações!
Sinal costuma ir pro espaço se o número era negativo e você mandou pra uma variavel sem sinal.
Eu mesmo, como se isso fosse grande coisa, já me deparei com uma dessas tambem, era uma variavel do tipo texto, digo, alfanumérica de duas posições que tivemos de altera-la para tres posicoes e por algum motivo a verificacao de zeros era feita com ‘00‘ e ai deu merda, e das grandes, afinal ‘ 00’ (branco zero zero) não é ‘000’
Lembre-se sempre de perguntar se a variavel numerica que você esperava receber é realmente numerica, tem um teste bem simples que é o IF seguido do nome da variavel e IS NUMERIC, fica assim no código:
77 CEBOLA-N PIC S9(4) COMP VALUE 0.
Programa executou e tals e ai uma bela hora você se indaga se ainda esta tudo certo com a variavel.
IF CEBOLA-N IS NOT NUMERIC THEN DISPLAY ‘VARIAVEL CEBOLA-N COM VALOR NÃO NUMERICO -’ CEBOLA-N ‘-’ END-IF
Delimitado entre hífen pra saber direitinho onde esta o conteudo da variavel”
Tente validar os tamanhos recebidos de areas de comunicação
Se possivel valide os dominios das variaveis
Movimentações de variáveis alfanumericas de tamanhos diferentes geralmente trunca, ficando o receptor do campo preenchido até o seu tamanho com o conteudo do dado que foi movimentado. Atualmente (Versao Cobol 6.2) em movimentações utilizando o comando MOVE sem substring não é mais para existir a possibilidade de ir sujeira, mas nunca se sabe e sempre tem algum mago do Cobol que faz alguma bruxaria que até a Grace duvidaria.
Em caso de erros programados, desde que possível, indique a variavel e o valor que ela continha no momento. Hum… mas qual variável ? Se for teste especifico de uma variavel ela mesmo já ajuda, se for algo genérico, bom, nesse caso é interessante descobrir o que seria um dado chave para tentar localizar mais informações na hora da analise do erro, um número de cartão de crédito, CPF, agencia e conta, número do celular, enfim, evidencias que ajudem a identificar no futuro o que pode ter ocorrido que gerou o erro.
Contas, movimentações e manipulação de dados
Temos as básicas que é o Add, o Subtract, o Divide e o Multiply, desde a versão 4.2 do Cobol se você quiser fazer um COMPUTE no lugar das operacoes básicas o compilador otimiza e se for interessante troca o compute por alguma das basicas automaticamente sem perda de performance ou algo do tipo. Cada uma das operações possui algumas nuances e variações, mas nada que não de pra entender facilmente na leitura do programa ou dando uma consultada no manual do Cobol. A multiplicação, divisão e o compute aceita arredondamento e truncamento. A divisão oferece suporte a resto. Regras de parenteses também são validas, sendo os internos resolvidos primeiro.
Se você não inicializou suas variáveis colocando a clausula values, sugiro que o faça, ah mas aqui no Shop nao deixa, nao usam, seilá qual for a desculpa que te deem indague o porque, se não usarem LOCAL-STORAGE pergunte também, mas enfim, se você não inicializou ou precisa inicializar/resetar alguma variavel ou grupo para seu valor inicial, utilize o comando INITIALIZE que deixa você inicializar numericos com um numero qualquer que você deseje e alphanumericos com algum texto de sua preferencia, vai que você não gosta de espaços em branco!
Nas contas como já disse anteriormente tente sempre usar a clausula on size error, pode te tirar de umas belas enrascadas, igual quando você vai fazer um loop, coloca se der uma segunda condição de parada, vai que o que você previu e que aconteceria de boa resolveu não rolar e ai seu programa fica no laço indefinidamente até o CICS / IMS se ligar que o programa esta em loop ou o tempo de execução do Batch acabe.
O uso de tabelas internas de mais de duas dimensões não é muito recomendavel por razoes de entendimento, mas por vezes e se for algo que vai fazer SUA lógica (maiuscula no SUA) ficar muito mais simples e rapido a codificação, manda ver, mas por favor comente direitinho o que você esta fazendo, tem vezes que o óbvio é tão obvio que os outros não vão conseguir enxergar. Enfim, você tem o poder, use com responsabilidade! Tabelas indefinidas (sem fronteiras) ou com depending com as ocorrencias vindo de outros componentes (linkage, arquivo, db2 etc) toma cuidado porque da versão 6.2 pra cima pode dar problema dependendo do jeito que esta implementado a lógica no programa, eu costumo criar uma variável após essas tabelas, algo como um nivel 77 inicializado com um valor fixo e que de vez em quando eu pergunto se ele ainda esta lá, o que acaba de maneira tosca mas garante que a tabela ainda não invadiu área de memoria que em tese não era dela.
No uso de substrings anote direitinho os deslocamentos e se for algo complexo comenta pro amiguinho que for dar manutenção pra ele não perder tempo tentando entender sua lógica. Geralmente o pessoal usa pra movimentar/converter data de MM/DD/AAAA pra AA/MM/DDDD ou algo do tipo, eu pessoalmente gosto de variavel de data ter tudo o nome que é o que é, tipo dia é dia, mes é mes e ano é ano e uso o “move corresponding” mas tem gente que desconhece e quando é apresentada ao comando age como a maioria da galera que mexe com mainframe quando vê novidades, rechaça o novo.
Tamanho das variáveis
Saber determinar o tamanho de variáveis Cobol não é nenhum bicho de 7 cabeças, mas as vezes é legal aprender porque vai que você um dia vai trabalhar com dado armazenado hexadecimal ou mesmo vai abrir um arquivo na mão e ele tem variaveis comp ou comp-3 e onde você esta trabalhando não tem nenhum editor/visualizador de arquivos (exemplo, file master, file AID, file manager etc) ou ainda você vai rodar um utilitario de SORT para extrair ou formatar alguma informação do arquivo.
Lá vamos nós!
Uma vez acho que o Nakanish me falou algo mais ou menos assim “Saber o tamanho que a sua variavel ocupa na memória é importante, pois as vezes você pode se deparar com algo que não esta preparado para tratar e sabendo o seu tamanho você diminui o risco de melar outras áreas de memória que não tem nada a ver com o que você irá trabalhar.
O COBOL, como já disse, possui basicamente só dois tipos de variaveis PIC 9 ou PIC X, respectivamente numerica e alfanumerica. Se a variavel estiver no programa declarada bonitinha sem nenhum “atributo” elas são do tipo display, ocupando 1 byte para cada numero ou caracter. O que chamo de atributo é a clausula USAGE do COBOL que vou explicar logo na sequencia.
Agora entra um pouco da arquitetura do mainframe e história, mas aceite que a IBM teve uma boa sacada lá nos primórdios da computação e conseguiu armazenar dados em memória/arquivo de maneira “compactada” isso quase que de maneira “transparente” pro programador.
Isso posto, tenha em mente que existe uma forma de armazenar numeros no mainframe na qual cada byte contem dois digitos (exceto o ultimo meio byte mais a direita que contem o sinal), esse tipo de “usage” é conhecido como Packed-Decimal ou COMP-3. Lembre sempre de usar com numero impar de digitos porque o tamanho da variavel vai ser quantidade de digitos + 1 / 2, exemplo PIC S9(5) COMP-3 poderá armazenar até 5 digitos, 12345 por exemplo mais o sinal e ocupará “apenas” 3 bytes em memória (5 + 1 /2). Lembre-se do contexto histórico, isso foi criado em 1964 e um mísero byte fazia muita diferença! Por razões de compatibilidade e da própria arquitetura do mainframe esse “formato” de campo continua funcionando até hoje e tem muita aplicação que ainda o utiliza, novos programas continuam utilizando mas na minha pobre concepção e dos testes que já vi e dos papers que li, atualmente (2018) não faz mais a menor diferença.
Existe outra forma muito mais intuitiva para os computadores que é o formato Binary ou COMP, esse não tem segredo e tem analogos em quase todas as linguagens de programação, os números são armazenados em formato de acordo com a definição da picture sendo smallint, integer e decimal, não tão bonitinho assim, na verdade são ranges. Ocupando 2 bytes de tamanho (half-word) temos PIC S9 até S9(4) que armazena até 7FFF ou se preferir 32767 porque o primeiro bit guarda o sinal e tals, mas enfim, seguido de uma word (algo como um Integer) que vai de S9(5) até S9(9) com 4 bytes de tamanho ocupado para os numeros que lá existir, e a double word que seria o Decimal e vai de PIC S9(10) até S9(18) ocupando 8 bytes. Da pra tirar o sinal tambem e ai no caso do PIC 9(4) COMP, da pra ir até 65535.
Existem outros “USAGE” para numeros em COBOL e tem também a opção de compilação de ARITH(EXTEND) pra deixar os numeros irem até o infinito, minto deixa ir até 31 digitos, pra uma aplicação COBOL digo que é mais que o suficiente, se precisar de algo mais preciso que isso peça pro pessoal de subrotinas criar uma em Assembler.
Caso encontre algo que não expliquei dê uma lida nos manuais da IBM, nesse caso só tem 2 o User Guide o o Programming Guide, só toma cuidado pra pegar o da mesma versão que você esta usando porque as vezes pode dar alguma diferença no tratamento dependendo de como o programa foi compilado e qual versão do Cobol é o manual que você esta lendo, mas isso vai ser bem raro, se não conseguir se virar sozinho, pergunta pra algum colequinha ou faz um programinha de 5 linhas pra ver como se comporta sua variavel.
As variaveis do Cobol seguem uma hierarquia numerica, sendo conhecida como nivel, as variaveis de “item de grupo” são do nivel 01 e possuem ou não outras variaveis de maior nivel embaixo delas, geralmente são usados numeros impares para essa tarefas, vao de 01 até 49, existem outros 3 tipos especiais de niveis, o 88 para testes logicos, o 77 para variaveis sem subordinação, e o 66 para renomear partes de alguma variavel. É muito comum o uso de “Redefines” que são redefinicoes das variaveis sob um determinado nivel para receberem dados de outros tipos ou mesmo um registro totalmente diferente mas que ocupara a mesma area definida anteriormente, geralmente o uso das redefinicoes leva a problemas com a utilizacao das variaveis, portanto, sempre cheque se o conteudo de suas variaveis estão de acordo com o esperado por você para aquele momento/situação.
Por exemplo, veja essas variaveia abaixo:
01 GDA-VARIAVEIS-DIVERSAS. 03 GDA-DATA-PSST VALUE ‘20AAMMDD’. 05 ANO. 07 PIC 99. 07 AA PIC XX. 05 MES PIC XX. 05 DIA PIC XX. 66 GDA-DATA-AAMMDD RENAMES AA THRU DIA.
GDA-VARIAVEIS-DIVERSAS é o item de grupo (nivel 01), GDA-DATA-PSST é um outro item de grupo subordinado ao nivel 01 anterior, ele inicializa uma area em memoria com o valor fixo 20AAMMDD, que tera os valores de Ano, mes e dia preenchidos no processamento em algum comando move e que podera referenciar uma data com 6 digitos no formato ano, mes dia, como esta renomeado no nivel 66, esse é um exemplo puramente didatico, no dia a dia você não deve se deparar com o nivel 66, mas eu sinceramente adoro!
O nivel 77 pode ser utilizado para verificar se uma tabela invadiu espaço em memoria, por exemplo:
01 TABELAS-INTERNAS. 03 TAB1-DADOS-TABELA OCCURS 100 TIMES ASCENDING KEY IS TAB-COD INDEXED BY I1. 05 TAB1-COD PIC S9(4) COMP VALUE 0. 05 TAB1-IND USO PIC X VALUE ‘N’. 05 TAB1-NOME PIC X(30) VALUE SPACES.
77 IND-ESTOURO-TAB PIC X VALUE ‘@’. 88 TABELA-OK VALUE IS ‘@’.
E lá pelas tantas no processamento do seu programa você pergunta pelo nivel 88 pra ver se ainda esta tudo ok, se não tiver, tem que parar o processamento porque aconteceu alguma caca. Ficaria algo como:
IF NOT TABELA-OK THEN
Processamento de erros padrao de seu Shop
END-IF
Processamento Batch
Esse aqui ainda hoje é o carro chefe do Cobol, que é o processamento agendado, rotineiro, que faz sempre a mesma coisa, sem interferencia humana, amarrado com condições de outros processamentos, com dias e horarios especifidos.
São conjuntos de procedures que executam programas/utilitários/funções que realizam operações massivas com dados (seja eles armazenados em arquivos, banco de dados, filas - só lembrei desses no momento), desde uma simples ordenação dos registros até mesmo a confirmação de toda movimentação que ocorreu em uma conta corrente “durante o dia”.
Antigamente existia uma tal de janela Batch, ou janela on-line, dependende de onde você estivesse trabalhando chamavam de um nome ou do outro, mas basicamente era o horario que “a maquina” estava dedicada quase que exclusivamente para um dos tipos de processamento… para o sistema financeiro em geral era das 9 as 16, coincidentemente era o horario de funcionamento das agências, periodo que tinha a maior quantidade de acessos on-line ao sistema, muitos funcionarios, muitos caixas eletronicos, enfim era o horario que o sistema tinha que dar o seu melhor para atender a clientela. Porém desde o advento dos smartphones e seu uso para transações bancarias essa janela perdeu um pouco do sentido pois a grande maioria dos acessos aos sistemas bancarios não ocorre mais nas agências e esse periodo não faz mais sentido.
Essa janela era o periodo que o processamento Batch era evitado ao máximo, quando rodava a prioridade dentro do mainframe era baixa, porque poderia “dar concorrencia”, ainda (2018) hoje por incrivel que pareça ainda existem instalações que possuem janelas de processamento e ainda temem a concorrência, uma pena pois as atualizações de hardware e software que o mainframe recebeu nos últimos 20 anos faz com que esse tipo de problema/situação passe despercebida, mas precisa mudar muita coisa que como já disse no inicio do livro, quem pode mudar é receoso e reticente e os novatos como nós - sim ainda me considero um novato - não tem força embora tenha todos os argumentos para fazer a mudança.
O conjunto de rotinas de um determinado sistema que rodam sequencialmente e com dependencias entre si, de horario, de recepção de arquivos e outras condições é conhecida como malha batch, e é gerenciada por softwares especificos e mantida pelo pessoal de produção.
Depois dessa breve introdução, deixa eu comentar um pouco sobre como o Cobol trabalha com arquivos e como ele realiza esse processamento. Na maioria dos casos o processo vai ter um ou mais arquivos de entrada, realiza processamento desses arquivos. Pode ser que o programa realize um balance line para gerar uma saida com dados originados desses arquivos, pode chamar um processo para validar dados e gerar um arquivo de saida apenas com dados validos, pode ir a um banco de dados obter mais informações, pode realizar calculos diversos, pode ter inumeras regras de negócio em formato “hard-code” dentro do programa cobol, pode chamar um motor de regras, pode iniciar outros processos, enfim, uma infinidade de situações pode ser encontrada, o limite é a imaginação do desenvolvedor.
O tipo mais basico de programa batch que você pode encontrar é um famigerado le-grava, que é um programa que le um arquivo de entrada, faz alguma coisa qualquer nos dados e grava um arquivo de saida, uma vez o Mané passou um lê grava pra gente fazer que eu e o Michel ficamos de sexta até uma segunda pra terminar, nunca acredite quando te falarem que é coisa rapida, só um ifizinho ou mesmo tem um le-grava pra segunda!
O Cobol trabalha extremamente bem com arquivos, as estruturas dos registros são pre-definidas, a maioria das vezes os registros de um arquivo tem tamanho iguais, seguem o mesmo layout, mamão com açúcar, mas tem os cabeludos que algum mago lá atrás resolveu ter uma grande ideia e saiu fazendo mágica, se pegar um arquivo desses que tenha que dar um talento no programa, só posso te desejar boa sorte, a lógica será rebuscada e via de regra usará tabelas com mais de uma dimensão com tamanho variável e sem comentário algum no código, ah, e cheio de GoTo e às vezes com ALTER.
O esquema é basico e segue igual há meio século, abre os arquivos que serão utilizados realiza a leitura, faz a gravação do arquivo de saida e fecha os arquivos.
Dependendo de onde você estiver trabalhando podem pedir pra verificar se os comandos de acesso a arquivos deram certo - é simples, uma variavel que você mesmo define e é carregada pelo cobol quando usa os servicos de arquivo do sistema operacional, é o File Status, mas pode ser que não tenham e o proprio Language Environment vai cuidar pra você quando der erro.
Não é pra ter muito segredo, pegando um esqueleto de exemplo deve dar sucesso sem problemas. Lembre-se de limpar o programa que foi usado como base, dê um talento pra tirar as variáveis que não for usar, adequar com o padrão que estiver em uso no momento, reordenar para que fique com visao macro dos processos e dar o seu toque especial, aquele que quando alguém pegar seu código saberá que foi você que fez!
O Cobol precisa estar ligado/linkado direitinho com o JCL que vai executa-lo para que possa acessar os arquivos corretamente e não dar problema, o DD name do JCL é o nome do arquivo que esta no ASSIGN do Cobol, a definição de arquivo esta bem simples tanto para o Cobol para o JCL, muito dos parametros que você encontrar já estão obsoletos e totalmente desnecessários, fica a dica, sempre que puder tire tudo que não for mais necessário, deixe com o sistema que ele cuida (na maioria das vezes) melhor que a gente.
Essa parte de linkar os arquivos com o JCL da execução tem que informar os dados na Environment Division -> Input-Output Section, mais especificamente em File-Control, lá coloca o nome externo dos arquivos, o file organization, como é o acesso a eles e o file status.
Ilustrando:
SELECT ENTRADA1 ASSIGN TO DD1
ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS FS-ENTRADA1.
Não se espante se encontrar apenas um SELECT ENTRADA ASSIGN TO DD1, talvez sua instalação não ligue para verificacao de file status e deixe os erros de acesso a arquivos por conta das proprias evolucoes do z/OS e trabalhe com o tipo de acesso e organizacao do arquivo padrão, que é o arquivo sequencial sem frescura! Tem o sequencial, que é o padrãozao, tem record sequential, line sequential mas tem tambem o indexado e o relativo, se pans tem outros mas nunca usei.
Depois de definido o nome do arquivo e suas caracteristicas e acessos, você precisará ir na Data Division -> File Section e inserir a File Definition do arquivo, fica assim
FD ENTRADA1
RECORDING MODE IS F
LABEL RECORD STANDARD
BLOCK CONTAINS 0 RECORDS.
01 RG-ENTRADA1 PIC X(72).
Aqui é feito a outra referencia do nome do arquivo com seu tamanho ocupado em memoria. O record mode F é fixo, tem o V tambem que é variavel, o block contains 0 deixa que o mainframe se diverte, se você for muito das antigas pode calcular a melhor blocagem e colocar aqui, hoje em dia quase ninguem mais usa algo diferente de 0. Aqui esta ilustrado igual na escola quando você aprende algo bem simpes e depois no exercicio já aparece algo mais elaborado e na prova cai um negocio que ninguem nunca viu! Calma e o que não entender ou se deparar com algo que nunca viu, vá atrás dos manuais, eles tem a resposta pra quase tudo!
Os arquivos podem ser de entrada, saida (do zero, arquivo novinho ou mesmo para adicionar registros depois do final, engordar) ou de entrada/saida, você vai regravar algo nele.
Por mais incrivel que pareça, se é sequencial é sequencial, nem adianta tentar voltar, pular ou algo do tipo, é do começo até o fim, ou até parar depois de n registros ou quando abendar, mas pra retomar de onde parou, siga com um não dá, embora dê, mas não de maneira nativa do Cobol, quem sabe um dia vou trampar por lá e implemento isso! Porque de sugestão, igual delay menor de 1 segundo no CICS ainda não aceitaram!
Sobre os arquvios indexados, leia-se no mainframe como arquivo VSAM, eles terão organization Indexed, Access Mode geralmente Random - mas existe o sequencial e o aleatorio (random) - e uma record key (única, sem repetição) mas pode ter alternate record keys essas podem repetir e ter mais de uma.
Sequencial já falei acima, sem maiories detalhes.
O Random pode acessar diretamente um registro ou ir navegando no arquivo de acordo com a chave, nao da pra ir lendo na sequencia ou pulando um ou ouro, tem que saber a chave pra efetuar a leitura.
E tem o Dynamic que possibilita o acesso sequencial ou randomico.
Na clausula FD (File Description (FD) Entry) desses arquivos indexados você precisa informar a(s) mesma(s) “chave(s)” que foi definida na Input-Output Section.
Esses arquivos quando for realizar a leitura, o comando READ pode ter um NEXT RECORD pra ir pro registro com a proxima chave ou move a chave antes e usa o read “normal”. Da pra dar aquele sambarilóvi e usar um invalid key quando usar READ arquivo KEY IS chave, mas geralmente não vai precisar.
Se for ler e sabe de onde comecar recomenda-se o uso do START que vai deixar o “ponteiro” no ponto de bala pra realizar a leitura, é bem amplo e deixa utilizar quase que a totalidade dos operadores (maior, menor, igual e suas combinações) para “ponteirar” a leitura.
Existe a possibilidade de DELETE, nunca vi usarem, mas em todos os casos, vai que você pega um programa que o faça, não se assuste, o comando é DELETE o nome do arquivo que deram na FD seguido de RECORD, só não funciona pra arquivos de organizacao sequencial. você tem que ler antes se tiver lendo sequencialmente e pode apagar só movendo a chave quando for direto ou random, chaves alternadas não funciona.
Se tentou apagar mas a chave não tinha é interessante dar uma testada no file status ou mesmo usar a clausula invalid key do proprio comando delete.
No caso de gravação pode ser de um registro novo ou um update, o comando é um WRITE normal quando vai inserir um cara novo, é bom lembrar que o arquivo tem que ser aberto com EXTEND se quiser adicionar uns caras a mais, se o arquivo estiver zerado nao faz nem sentido usar os acessos sem ser o sequencial…. Bom, normal é usar o I/O ou OUTPUT. Movimenta-se os dados novos pra area definida no FD e manda gravar (ou regravar ai usa REWRITE no lugar do WRITE e tem que ter lido o registro antes, mentira, da pra ir direto, mas eu recomendo fortemente que leia antes), simples assim. Afinal de contas a chave primaria nao da pra ser alterada via rewrite, na real, tem que deletar o registro e criar um novo com outra, nem sei se essa frase fez sentido, mas imagina um banco de dados que você vai tentar alterar a chave primaria de um registro, não dá, é um registro novo!
Resumindo, arquivos indexado deixar o programa acessar diretamente um registro utilizando a chave.
Existe um outro tipo de arquivo, os arquivos relativos, utilizamos no log do FAS quando da evolução devido a limitação dos 4GB dos VSAM lineares com RBA, eu fui voto vencido, eu utilizaria o XRBA, mas era incipiente e pra variar seriamos piloto da novidade, mas ainda acho que seria uma boa solução, a mudança seria minima, mas enfim, bola pra frente. Os arquivos relativos são basicamente arquivos indexados, mas a “CHAVE” é o numero do registro no arquivo, e pode por isso ser acessados diretamente através dessa chave.
O acesso direto aos registros em um arquivo relativo (os VSAM desse tipo são conhecidos como Relative record number (RRN)) esse acesso é geralmente mais veloz do que um arquivo indexado (com chave “normal”), uma vez que não é necessário tempo para pesquisar e atualizar os índices (afinal, não existe o arquivo de indice… ele foi “incorporado” no numero do registro). Ah, na File-Control, “relative files must always be defined with the clause Organization is Relative”, o Access mode pode ser qualquer um 3 tipos, sequencial, randomico ou dinamico. A clausula da chave fica como RELATIVE KEY IS Numero-do-Registro, sendo no numero do registro definido na working, local ou mesmo na linkage, como um numerico.
Leitura, inclusao de registro e atualizacao nao tem segredos, se for alterar tem que lembrar de abrir como I-O, o DELETE muda o esquema porque deixa fazer de dois jeitos:
1 - faz a leitura inteira do registro antes porque necessita dos dados da clausula FD e tambem tem que ser aberto como I_O, lembrar que fica um buraco no lugar do regsitro deletado e não vai ter invalid key nessa, vai ter que perguntar pelo file-status. 2 - move o numero do registro e manda apagar.
Os arquivos relativos tambem podem ser processados sequencialmente ou “sequencial-skipped”, que você aponta em um registro determinado e dali pra frente manda ver na leitura de um por um na sequencia.
Desvantagem que vejo são os buracos que por ventura podem existir no arquivo, isto é, se o registro 3 não existir.
Não fique preocupado com os conceitos, pois é meio abstrato quando estamos lendo essas definições, mas quando se deparar com um programa que utilize algum arquivo desses que não são sequenciais (que é o padrao e eu diria de chute sem muito erro que deve ser uns 90% dos arquivos que você vai encontrar). Fique tranquilo que você não precisará reinventar a roda, vai de copia e cola, mas tente entender o que esta fazendo, por favor!
Nota de rodapé, atualmente e desde que comecei a trabalhar com COBOL o maximo de caracteres que compõem o nome de uma variavel/section/arquivo é de no maximo 30 bytes,
Last updated