Translate

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

terça-feira, 5 de maio de 2026

🔥☕ PACKAGE, PLAN, DBRM E O SUBMUNDO DA COMPILAÇÃO Db2 — O GUIA PADAWAN DO COBOL MAINFRAME ☕🔥

 

Bellacosa Mainframe explica como funciona um programa COBOL com DB2

🔥☕ PACKAGE, PLAN, DBRM E O SUBMUNDO DA COMPILAÇÃO Db2 — O GUIA PADAWAN DO COBOL MAINFRAME ☕🔥

Todo programador COBOL iniciante passa por isso.

Você escreve:

EXEC SQL
SELECT *
FROM EMPLOYEE
END-EXEC.

compila…

e de repente aparecem criaturas malignas como:

  • DBRM
  • PACKAGE
  • PLAN
  • BIND
  • DSNHPC
  • SQLCODE -805
  • SQLCODE -818

E o padawan pensa:

“Mas eu só queria fazer um SELECT…”

☕🔥

Então vamos entrar no verdadeiro submundo do Db2 z/OS.


☕ O MAIOR SEGREDO DO Db2

O Db2 NÃO executa SQL diretamente do fonte COBOL.

Ele precisa:

  • analisar SQL
  • validar objetos
  • escolher access path
  • gerar runtime structures

Por isso existe toda a cadeia:

SOURCE

PRECOMPILE

DBRM

COMPILE

LINK

BIND PACKAGE

BIND PLAN

RUN

🔥 VISÃO GERAL DA ARQUITETURA


☕ SOURCE COBOL

Seu programa original.

Exemplo:

EXEC SQL
SELECT EMPNO
INTO :WS-EMPNO
FROM EMPLOYEE
END-EXEC.

Dataset típico:

USERID.COBOL.SOURCE(MEUCOB)

🔥 STEP 1 — PRECOMPILE

Programa usado:

//DB2PC EXEC PGM=DSNHPC

☕ O QUE É O DSNHPC?

É o:

Db2 PRECOMPILER

🔥 O QUE ELE FAZ?

Ele:

✅ encontra EXEC SQL
✅ valida sintaxe SQL
✅ remove SQL do COBOL
✅ gera COBOL expandido
✅ gera DBRM


☕ RESULTADO DO PRECOMPILE

Saídas:

SaídaFunção
COBOL expandidoserá compilado
DBRMusado no BIND

🔥 O QUE É O DBRM?

DBRM =

DATABASE REQUEST MODULE

☕ PENSE NO DBRM COMO:

“o extrato SQL do seu programa”

Ele contém:

  • SQL do programa
  • informações internas Db2
  • metadados SQL

🔥 O DBRM NÃO É EXECUTÁVEL

Isso é importante.

Ele NÃO roda.

Ele apenas alimenta o BIND.


☕ ONDE O DBRM É SALVO?

Normalmente em:

//DBRMLIB DD DSN=USERID.DBRM.LIB(MEUPRG)

Dataset típico:

USERID.DBRM.LIB

Tipo:

PDS ou PDSE

🔥 EXEMPLO REAL DE PRECOMPILE

//DB2PC EXEC PGM=DSNHPC,
// PARM=('HOST(IBMCOB),APOST')

☕ EXPLICANDO OS PARÂMETROS


HOST(IBMCOB)

Define linguagem COBOL IBM.


APOST

Aspas simples delimitam strings SQL.


SOURCE

Mantém fonte expandido legível.


XREF

Gera cross reference.


DATE(ISO)

Formato ISO de datas.


🔥 STEP 2 — COMPILE COBOL

Programa:

//COB EXEC PGM=IGYCRCTL

☕ O QUE ACONTECE?

Agora o compilador COBOL compila:

o COBOL expandido gerado pelo precompiler

🔥 ELE NÃO COMPILA MAIS EXEC SQL

Porque o precompiler já removeu.


☕ SAÍDA DO COMPILE

Gera:

OBJECT MODULE

temporário.


🔥 STEP 3 — LINK-EDIT

Programa:

//LKED EXEC PGM=IEWL

☕ O QUE O LINK FAZ?

Une:

  • objeto COBOL
  • bibliotecas runtime
  • chamadas Db2

🔥 RESULTADO

LOAD MODULE EXECUTÁVEL

☕ ONDE FICA O LOAD MODULE?

Exemplo:

//SYSLMOD DD DSN=USERID.LOADLIB(MEUPRG)

Dataset típico:

USERID.LOADLIB

🔥 AGORA ENTRA O VERDADEIRO MUNDO Db2

Até aqui temos apenas:

programa COBOL executável

Mas o Db2 ainda NÃO sabe nada sobre ele.


☕ STEP 4 — BIND PACKAGE

Programa:

//BIND EXEC PGM=IKJEFT01

🔥 O QUE É O PACKAGE?

PACKAGE é:

o SQL compilado e otimizado do programa

☕ O PACKAGE CONTÉM

✅ access paths
✅ SQL otimizado
✅ metadados
✅ permissões
✅ informações de runtime


🔥 QUEM CRIA O PACKAGE?

O comando:

BIND PACKAGE

☕ O BIND USA:

  • DBRM
  • catálogo Db2
  • índices
  • estatísticas
  • permissões

🔥 O ACCESS PATH NASCE AQUI

Db2 decide:

  • index scan?
  • tablespace scan?
  • join order?
  • sort?
  • parallelism?

☕ ONDE PACKAGE É ARMAZENADO?

No próprio catálogo Db2.

Tabelas internas como:

SYSIBM.SYSPACKAGE

🔥 NÃO FICA EM PDS

Isso pega MUITOS iniciantes.

PACKAGE NÃO fica em dataset.

Fica dentro do Db2.


☕ EXEMPLO DE BIND PACKAGE

DSN SYSTEM(DBCG)

BIND PACKAGE(MYCOLL)
MEMBER(MEUPRG)
ACTION(REPLACE)
ISOLATION(CS)
VALIDATE(BIND)
EXPLAIN(YES)

🔥 EXPLICANDO OS PARÂMETROS


PACKAGE(MYCOLL)

Collection/package name.


MEMBER(MEUPRG)

Nome do DBRM.


ACTION(REPLACE)

Substitui package antigo.


ISOLATION(CS)

Cursor Stability.


VALIDATE(BIND)

Valida objetos no bind.


EXPLAIN(YES)

Salva access path.


☕ STEP 5 — BIND PLAN

Agora vem o PLAN.


🔥 O QUE É O PLAN?

PLAN é:

um agrupador de packages

☕ ANTIGAMENTE

Db2 antigo usava:

PLAN + DBRM

🔥 Db2 MODERNO USA:

PLAN + PACKAGE

☕ O PLAN FUNCIONA COMO

“container lógico de execução”

🔥 EXEMPLO

BIND PLAN(MYPLAN)
PKLIST(MYCOLL.*)

☕ PKLIST

Lista packages autorizados.


🔥 ONDE O PLAN FICA?

Também no catálogo Db2.

Tabela:

SYSIBM.SYSPLAN

☕ EXECUÇÃO — RUN

Agora sim:

RUN PROGRAM(MEUPRG)
PLAN(MYPLAN)

🔥 O FLUXO EM EXECUÇÃO

Programa chama:

PLAN

PACKAGE

SQL

Db2 Engine

☕ ANALOGIA PADAWAN

Imagine:


☕ SOURCE

Receita escrita.


🔥 DBRM

Lista dos ingredientes.


☕ PACKAGE

Receita otimizada pelo chef.


🔥 PLAN

Cardápio do restaurante.


☕ LOAD MODULE

Cozinheiro executando.

☕🔥


🔥 ERROS MAIS FAMOSOS


☕ SQLCODE -805

O terror dos iniciantes.

PACKAGE NÃO ENCONTRADO

CAUSAS

✅ bind não executado
✅ collection errada
✅ package apagado
✅ plan errado


🔥 SQLCODE -818

TIMESTAMP MISMATCH

SIGNIFICA

LOAD MODULE ≠ PACKAGE atual.


ACONTECE QUANDO

recompila COBOL mas não rebinda package.


☕ SQLCODE -204

objeto não encontrado

NORMALMENTE

schema/qualifier errado.


🔥 SQLCODE -551

sem autorização

☕ COMO INVESTIGAR PROBLEMAS


🔥 VER PACKAGE

SELECT *
FROM SYSIBM.SYSPACKAGE
WHERE NAME = 'MEUPRG'

☕ VER PLAN

SELECT *
FROM SYSIBM.SYSPLAN
WHERE NAME = 'MYPLAN'

🔥 DISPLAY PACKAGE

-DISPLAY PACKAGE(*)

☕ O QUE O JUNIOR PRECISA ENTENDER


🔥 O COBOL NÃO EXECUTA SQL DIRETAMENTE


☕ O PACKAGE É O SQL “COMPILADO”


🔥 O PLAN ORGANIZA EXECUÇÃO


☕ O DBRM É A PONTE ENTRE FONTE E PACKAGE


🔥 O BIND DEFINE PERFORMANCE


☕ O ACCESS PATH NASCE NO BIND


🔥 O MAIOR SEGREDO DO Db2

Muitos problemas de produção NÃO estão no COBOL.

Estão em:

  • package inválido
  • bind errado
  • access path ruim
  • rebind problemático
  • estatísticas ruins
  • qualifier incorreto

☕ A VERDADEIRA MAGIA

Enquanto frameworks modernos escondem tudo…

o programador mainframe aprende:

  • como SQL realmente executa
  • como runtime funciona
  • como otimização nasce
  • como banco conversa com aplicação

E isso transforma um simples padawan COBOL…

num verdadeiro Jedi do Db2 z/OS. ☕🔥


terça-feira, 24 de setembro de 2024

Fluxo de Compilação de um programa COBOL com DB2

 

Bellacosa Mainframe e o fluxo de compilação cobol com db2

☕ Um Café no Bellacosa Mainframe

O Caso do Programa que Precisava de Duas Identidades

O Fluxo de Compilação de um Programa COBOL com Db2

A chuva caía sobre as janelas do CPD como uma sequência interminável de registros sendo gravados em um arquivo sequencial.

Do lado de dentro, os monitores 3270 lançavam uma luz esverdeada sobre as mesas. O relógio marcava 23h47. Os operadores já falavam baixo, como se soubessem que, depois de certo horário, os programas começavam a revelar segredos que escondiam durante o expediente.

Foi quando encontrei o programa.

Estava abandonado em uma biblioteca de fontes, cercado por COPYBOOKs, comandos SQL e comentários escritos por programadores que provavelmente já haviam se aposentado.

Na primeira linha, ele parecia apenas mais um programa COBOL.

Mas havia alguma coisa diferente.

No meio da PROCEDURE DIVISION, encontrei a pista:

EXEC SQL
    SELECT NOME_CLIENTE,
           SALDO_CONTA
      INTO :WS-NOME-CLIENTE,
           :WS-SALDO-CONTA
      FROM CLIENTES
     WHERE COD_CLIENTE = :WS-COD-CLIENTE
END-EXEC.

Aquilo mudava tudo.

Um compilador COBOL comum não saberia o que fazer com aquelas instruções.

EXEC SQL não era COBOL.

Era SQL infiltrado dentro de um programa COBOL.

O programa possuía duas identidades: uma destinada ao compilador COBOL e outra destinada ao Db2.

Para transformar aquele fonte em um módulo executável, seria necessário conduzi-lo por uma cadeia de interrogatórios, traduções, compilações, ligações e registros.

No mundo COBOL com Db2, ninguém sai do fonte diretamente para a execução.

Antes de chegar ao CICS, ao batch ou ao ambiente de produção, o programa precisa atravessar o chamado fluxo de compilação COBOL–Db2.

E cada etapa produz uma nova pista.


1. A cena do crime: o programa-fonte

Tudo começa com um membro contendo o código-fonte COBOL.

Em um ambiente tradicional, ele poderia estar em uma biblioteca como:

BANCO.DESENV.COBOL(PROGCLI1)

Dentro desse programa encontramos instruções COBOL normais:

MOVE 1001 TO WS-COD-CLIENTE.
DISPLAY 'INICIANDO CONSULTA'.

Mas também encontramos comandos SQL embutidos:

EXEC SQL
    SELECT NOME_CLIENTE
      INTO :WS-NOME-CLIENTE
      FROM CLIENTES
     WHERE COD_CLIENTE = :WS-COD-CLIENTE
END-EXEC.

Esses comandos são chamados de SQL estático embutido, ou embedded static SQL.

O termo “estático” significa que, em linhas gerais, a instrução SQL já está conhecida antes da execução do programa.

O Db2 pode analisar essa instrução previamente, determinar como ela poderá acessar as tabelas e registrar essas informações durante o processo de BIND.

Mas existe um problema.

O compilador COBOL não entende diretamente:

EXEC SQL

Ele entende MOVE, PERFORM, IF, EVALUATE, READ, WRITE e outras instruções da linguagem.

SQL pertence ao território do Db2.

Portanto, antes da compilação COBOL, alguém precisa separar as duas identidades do programa.

Esse alguém é o pré-compilador Db2.


2. O primeiro interrogatório: o pré-compilador Db2

O pré-compilador recebe o programa-fonte como entrada.

Sua missão é localizar todas as instruções existentes entre:

EXEC SQL

e:

END-EXEC

Quando encontra uma instrução SQL, o pré-compilador não simplesmente a apaga.

Ele realiza duas operações fundamentais.

Primeiro, substitui o SQL por chamadas que poderão ser compiladas como parte do programa COBOL.

Segundo, extrai informações sobre as instruções SQL e as registra em um arquivo chamado DBRM.

Assim, de um único programa-fonte surgem duas evidências:

Fonte COBOL com SQL
        |
        v
Pré-compilador Db2
        |
        +--> Fonte COBOL modificado
        |
        +--> DBRM

Essa divisão é a chave de todo o caso.

O programa passa a ter dois caminhos paralelos.

Um caminho segue para o compilador COBOL.

O outro segue para o BIND do Db2.

Mais tarde, os dois caminhos precisarão se reencontrar durante a execução.


3. O fonte modificado

Depois do pré-processamento, o SQL original não permanece exatamente como foi escrito.

Uma instrução como:

EXEC SQL
    SELECT NOME_CLIENTE
      INTO :WS-NOME-CLIENTE
      FROM CLIENTES
     WHERE COD_CLIENTE = :WS-COD-CLIENTE
END-EXEC.

é transformada em estruturas e chamadas que o compilador COBOL consegue processar.

O resultado é conhecido como fonte modificado, fonte traduzido ou fonte expandido, dependendo da terminologia usada no ambiente.

Esse fonte contém lógica responsável por conversar com a interface do Db2 em tempo de execução.

O programador normalmente não precisa editar esse código gerado.

Ele existe para que o compilador COBOL consiga trabalhar com um programa que originalmente continha SQL.

É como se o pré-compilador retirasse o estrangeiro da sala, traduzisse seu depoimento e entregasse ao compilador apenas aquilo que ele consegue compreender.


4. A ficha que acompanha o suspeito: SQLCA

Programas COBOL que acessam Db2 normalmente precisam de uma área chamada SQLCA, SQL Communication Area.

Ela pode ser incluída com:

EXEC SQL
    INCLUDE SQLCA
END-EXEC.

A SQLCA contém informações sobre o resultado da última instrução SQL executada.

Entre seus campos, o mais famoso é:

SQLCODE

O SQLCODE informa se a operação terminou corretamente ou se algo inesperado aconteceu.

Alguns valores comuns são:

SQLCODE = 0
Operação concluída com sucesso.

SQLCODE = +100
Nenhuma linha encontrada ou fim do resultado.

SQLCODE negativo
Ocorreu algum erro.

Exemplo:

EXEC SQL
    SELECT NOME_CLIENTE
      INTO :WS-NOME-CLIENTE
      FROM CLIENTES
     WHERE COD_CLIENTE = :WS-COD-CLIENTE
END-EXEC.

EVALUATE TRUE
    WHEN SQLCODE = 0
         DISPLAY 'CLIENTE: ' WS-NOME-CLIENTE

    WHEN SQLCODE = 100
         DISPLAY 'CLIENTE NAO ENCONTRADO'

    WHEN OTHER
         DISPLAY 'ERRO DB2. SQLCODE: ' SQLCODE
END-EVALUATE.

Um programa COBOL–Db2 que ignora o SQLCODE é como um detetive que interroga uma testemunha e sai da sala sem ouvir a resposta.


5. O segundo interrogatório: o compilador COBOL

Depois do pré-compilador, o fonte modificado é enviado ao compilador COBOL.

Agora o compilador encontra apenas estruturas que consegue entender.

Ele verifica:

  • sintaxe COBOL;

  • definição de variáveis;

  • compatibilidade de tipos;

  • referências a parágrafos;

  • COPYBOOKs;

  • tamanho de campos;

  • opções de compilação;

  • regras da linguagem.

Se tudo estiver correto, o compilador gera um módulo objeto.

O módulo objeto ainda não é o programa final pronto para executar.

Ele contém código de máquina e referências que ainda precisam ser resolvidas.

Podemos representar essa fase assim:

Fonte COBOL modificado
          |
          v
Compilador COBOL
          |
          v
Módulo objeto

Durante essa etapa, também é produzido o listing de compilação.

Esse listing pode mostrar:

  • erros;

  • avisos;

  • opções utilizadas;

  • mapa de dados;

  • referências cruzadas;

  • estatísticas da compilação;

  • mensagens do compilador.

O retorno da compilação costuma ser avaliado por meio do condition code do step.

Uma interpretação frequente é:

RC 0
Compilação concluída sem mensagens relevantes.

RC 4
Compilação concluída com avisos.

RC 8 ou superior
Existem erros que normalmente impedem a geração válida do programa.

Os significados exatos dependem das mensagens e das políticas do ambiente.

Um RC=4 não deve ser tratado automaticamente como “está tudo bem”.

Aviso também é pista.


6. O dossiê secreto: DBRM

Enquanto o fonte modificado segue para o compilador COBOL, o DBRM toma outro caminho.

DBRM significa:

Database Request Module

Ele contém uma representação das instruções SQL estáticas extraídas do programa.

O DBRM não é um programa COBOL executável.

Ele também não é uma tabela do Db2.

É uma espécie de dossiê contendo os pedidos de acesso ao banco de dados.

Nesse dossiê, o Db2 encontra informações sobre instruções como:

SELECT
INSERT
UPDATE
DELETE
DECLARE CURSOR
OPEN
FETCH
CLOSE

O DBRM será usado mais tarde durante o processo chamado BIND.

Sem BIND, o Db2 sabe que o programa tem intenções.

Mas ainda não concedeu autorização operacional para que essas intenções sejam executadas.


7. O BIND: quando o Db2 monta o plano

O BIND é uma das etapas mais importantes do fluxo.

Durante o BIND, o Db2 examina as instruções SQL registradas no DBRM.

Ele verifica:

  • se os objetos referenciados existem;

  • se tabelas, views e colunas podem ser localizadas;

  • se os tipos são compatíveis;

  • se o usuário responsável possui os privilégios necessários;

  • quais caminhos de acesso podem ser utilizados;

  • quais opções de isolamento e validação foram definidas.

O resultado normalmente é a criação ou atualização de um PACKAGE.

Em arquiteturas mais antigas ou em determinados ambientes, também pode existir o conceito de PLAN associado à execução.

De forma simplificada:

DBRM
 |
 v
BIND PACKAGE
 |
 v
PACKAGE Db2

O PACKAGE contém informações que o Db2 utilizará para executar o SQL estático.

Entre essas informações está o access path, isto é, o caminho escolhido para alcançar os dados.

Por exemplo, o Db2 poderá decidir entre:

  • utilizar um índice;

  • realizar uma varredura da tabela;

  • acessar índices em determinada sequência;

  • executar joins em uma ordem específica;

  • utilizar mecanismos de ordenação;

  • aplicar predicados em etapas diferentes.

O BIND é o momento em que o Db2 estuda o mapa do bairro antes de mandar seus agentes à rua.


8. VALIDATE(BIND) e VALIDATE(RUN)

Durante o BIND, uma opção importante pode determinar quando determinadas verificações serão exigidas.

Com:

VALIDATE(BIND)

o Db2 tenta validar os objetos e privilégios durante o próprio BIND.

Caso algo necessário não esteja disponível, o BIND pode falhar.

Com:

VALIDATE(RUN)

algumas verificações podem ser adiadas até o momento da execução.

Isso pode ser útil em certos cenários, mas também transfere parte do risco para o ambiente de execução.

Em uma produção crítica, adiar problemas não significa eliminá-los.

Significa apenas permitir que eles apareçam quando o programa estiver diante do usuário, do fechamento contábil ou do lote de milhões de registros.


9. O PACKAGE

O PACKAGE é o objeto Db2 que representa o SQL preparado para execução.

Ele está associado a elementos como:

  • nome da collection;

  • nome do programa;

  • versão;

  • opções do BIND;

  • access paths;

  • consistência do programa;

  • nível de isolamento;

  • qualificador;

  • proprietário;

  • validação.

Um comando conceitual de BIND poderia lembrar:

BIND PACKAGE(COLLECT1)
     MEMBER(PROGCLI1)
     ACTION(REPLACE)
     ISOLATION(CS)
     VALIDATE(BIND)

A sintaxe real depende do utilitário, da versão, do padrão de nomenclatura e das práticas adotadas na instalação.

O ponto essencial é que o PACKAGE vive no Db2.

Ele não é armazenado dentro do load module COBOL.

Isso explica por que o programa executável e seu PACKAGE podem existir em lugares diferentes e, mesmo assim, precisar corresponder exatamente.


10. O elo invisível: consistency token

Aqui surge uma das pistas mais elegantes do processo.

O módulo executável COBOL e o PACKAGE Db2 precisam reconhecer um ao outro.

Para isso, o processo utiliza uma identificação de consistência frequentemente relacionada ao consistency token.

O pré-compilador e o BIND produzem elementos que permitem ao Db2 verificar se o código executável corresponde ao PACKAGE disponível.

Considere este cenário:

  1. O programa foi pré-compilado.

  2. O DBRM foi gerado.

  3. O COBOL foi compilado.

  4. O load module foi criado.

  5. Um novo BIND não foi executado corretamente.

  6. O programa antigo ou um PACKAGE incompatível permaneceu no ambiente.

Durante a execução, o Db2 pode detectar que o executável e o PACKAGE não combinam.

O famoso resultado pode ser:

SQLCODE -805

Em linguagem de romance policial:

O sujeito apresentado pelo load module não era o mesmo registrado nos arquivos do Db2.


11. O terceiro interrogatório: o link-edit

O módulo objeto criado pelo compilador ainda contém referências externas.

Ele pode precisar de rotinas de tempo de execução, interfaces do Db2 e bibliotecas do sistema.

Por isso, o módulo objeto passa pelo link-edit, atualmente frequentemente executado pelo Binder do z/OS.

Fluxo:

Módulo objeto
      |
      v
Binder / Link-edit
      |
      v
Load module ou program object

Durante essa etapa, referências externas são resolvidas.

O resultado é colocado em uma load library, por exemplo:

BANCO.DESENV.LOAD(PROGCLI1)

Esse membro é o programa que poderá ser carregado para execução.

Dependendo da tecnologia e das opções adotadas, ele poderá ser chamado de:

  • load module;

  • program object;

  • módulo de carga;

  • executável.

É importante não confundir o load module com o PACKAGE.

Load module
Código COBOL executável.

PACKAGE
Representação executável das instruções SQL estáticas dentro do Db2.

Os dois fazem parte do mesmo caso, mas vivem em delegacias diferentes.


12. A montagem completa do fluxo

O fluxo clássico pode ser representado assim:

+----------------------------------+
| Fonte COBOL com SQL embutido     |
| EXEC SQL ... END-EXEC            |
+----------------+-----------------+
                 |
                 v
+----------------------------------+
| Pré-compilador Db2               |
+----------------+-----------------+
                 |
        +--------+--------+
        |                 |
        v                 v
+---------------+   +---------------+
| Fonte COBOL   |   | DBRM          |
| modificado    |   | SQL estático  |
+-------+-------+   +-------+-------+
        |                   |
        v                   v
+---------------+   +---------------+
| Compilador    |   | BIND PACKAGE  |
| COBOL         |   | no Db2        |
+-------+-------+   +-------+-------+
        |                   |
        v                   v
+---------------+   +---------------+
| Módulo objeto |   | PACKAGE       |
+-------+-------+   +---------------+
        |
        v
+---------------+
| Binder /      |
| Link-edit     |
+-------+-------+
        |
        v
+---------------+
| Load module   |
| ou program    |
| object        |
+---------------+

Na execução, os dois lados finalmente se encontram:

Load module COBOL
        |
        | chamada SQL
        v
Subsistema Db2
        |
        v
PACKAGE correspondente
        |
        v
Tabelas, índices e dados

Esse é o fluxo essencial.

Mas, como em toda investigação, os detalhes podem mudar conforme as ferramentas utilizadas.


13. Pré-compilador tradicional ou coprocessador SQL

Em ambientes modernos, o fluxo pode usar um SQL coprocessor integrado à compilação COBOL.

Nesse modelo, a compilação e o tratamento do SQL podem parecer uma única operação dentro do JCL ou da ferramenta de build.

Isso não elimina os conceitos fundamentais.

Mesmo com automação, continuam existindo:

  • análise do SQL;

  • geração de informações para o Db2;

  • compilação COBOL;

  • criação do executável;

  • criação ou atualização do PACKAGE;

  • necessidade de correspondência entre código e PACKAGE.

A diferença é que as ferramentas modernas escondem parte do corredor escuro atrás de uma porta automática.

O corredor continua lá.


14. Exemplo simplificado de programa

Considere o seguinte programa:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. PROGCLI1.

       DATA DIVISION.

       WORKING-STORAGE SECTION.

       01  WS-COD-CLIENTE     PIC 9(09) COMP-3.
       01  WS-NOME-CLIENTE    PIC X(40).
       01  WS-SALDO-CONTA     PIC S9(11)V99 COMP-3.

           EXEC SQL
               INCLUDE SQLCA
           END-EXEC.

       PROCEDURE DIVISION.

       0000-PRINCIPAL.

           MOVE 1001 TO WS-COD-CLIENTE

           EXEC SQL
               SELECT NOME_CLIENTE,
                      SALDO_CONTA
                 INTO :WS-NOME-CLIENTE,
                      :WS-SALDO-CONTA
                 FROM CLIENTES
                WHERE COD_CLIENTE = :WS-COD-CLIENTE
           END-EXEC

           EVALUATE TRUE
               WHEN SQLCODE = 0
                    DISPLAY 'CLIENTE: ' WS-NOME-CLIENTE
                    DISPLAY 'SALDO  : ' WS-SALDO-CONTA

               WHEN SQLCODE = 100
                    DISPLAY 'CLIENTE NAO ENCONTRADO'

               WHEN OTHER
                    DISPLAY 'ERRO SQL: ' SQLCODE
           END-EVALUATE

           GOBACK.

Antes que o programa execute, várias condições precisam ser atendidas:

  1. A tabela CLIENTES precisa existir.

  2. As colunas precisam existir.

  3. Os tipos precisam ser compatíveis.

  4. O programa precisa ser pré-processado.

  5. O código COBOL precisa ser compilado.

  6. O executável precisa ser linkado.

  7. O PACKAGE precisa ser criado.

  8. O usuário de execução precisa ter os acessos necessários.

  9. O load module e o PACKAGE precisam corresponder.

  10. O subsistema Db2 correto precisa estar disponível.

Uma única instrução SELECT pode parecer simples no fonte.

Mas por trás dela existe uma organização inteira trabalhando durante a madrugada.


15. Host variables: os informantes do COBOL

As variáveis utilizadas pelo SQL são chamadas de host variables.

Elas pertencem ao programa COBOL, mas são apresentadas ao SQL com dois-pontos:

:WS-COD-CLIENTE

Exemplo:

WHERE COD_CLIENTE = :WS-COD-CLIENTE

A coluna COD_CLIENTE pertence à tabela.

A variável WS-COD-CLIENTE pertence ao programa COBOL.

Os dois-pontos avisam ao pré-compilador:

Este nome não é uma coluna do banco. É uma variável do programa.

No INTO:

INTO :WS-NOME-CLIENTE

o Db2 coloca o valor retornado dentro da variável COBOL.

As host variables fazem a ponte entre dois mundos:

Mundo COBOL               Mundo Db2

WS-COD-CLIENTE   ------>  COD_CLIENTE

WS-NOME-CLIENTE  <------  NOME_CLIENTE

Se os tipos forem incompatíveis, o caso pode terminar em erro, truncamento ou comportamento indesejado.

Por isso, o programador deve entender tanto o PIC COBOL quanto o tipo da coluna Db2.


16. Variáveis indicadoras e o mistério do NULL

COBOL tradicional não possui um conceito nativo idêntico ao NULL do banco de dados.

Por isso, quando uma coluna pode conter NULL, utiliza-se uma indicator variable.

Exemplo:

01  WS-TELEFONE        PIC X(20).
01  WS-IND-TELEFONE    PIC S9(04) COMP.

No SQL:

EXEC SQL
    SELECT TELEFONE
      INTO :WS-TELEFONE :WS-IND-TELEFONE
      FROM CLIENTES
     WHERE COD_CLIENTE = :WS-COD-CLIENTE
END-EXEC.

Depois da execução:

Indicator >= 0
O valor normalmente está presente.

Indicator = -1
A coluna retornou NULL.

Sem a variável indicadora, um SELECT que encontre NULL pode gerar erro.

O programador iniciante frequentemente acusa a coluna.

Mas o verdadeiro culpado foi a ausência da indicator variable.


17. O PLAN

Em muitos ambientes Db2 for z/OS, packages são associados a um PLAN ou acessados por meio de mecanismos como collection lists.

Historicamente, o PLAN representa uma estrutura utilizada para a execução de programas SQL.

Simplificando:

Programa
   |
   v
PLAN
   |
   v
PACKAGE
   |
   v
SQL e dados

Em arquiteturas atuais, o PACKAGE ganhou grande importância porque permite maior modularidade.

Vários programas podem possuir seus próprios packages.

O PLAN pode utilizar uma lista de collections por meio de PKLIST.

Isso evita a necessidade de colocar todo o SQL de uma aplicação dentro de um único objeto gigantesco.


18. Erros clássicos da investigação

SQLCODE -805

Normalmente indica que o PACKAGE necessário não foi encontrado ou que existe incompatibilidade de identificação.

Possíveis causas:

  • PACKAGE não bindado;

  • collection incorreta;

  • versão incorreta;

  • ambiente errado;

  • load module e PACKAGE incompatíveis;

  • PLAN sem acesso à collection adequada.


SQLCODE -818

É frequentemente associado a incompatibilidade de timestamp ou consistency token entre o módulo executável e o DBRM/PACKAGE.

Em termos práticos:

  • o código foi compilado;

  • o BIND foi feito com outro DBRM;

  • as peças pertencem a versões diferentes.

É como tentar abrir um cofre novo com a combinação do cofre antigo.


SQLCODE -204

Objeto não encontrado.

Exemplo:

Tabela, view, alias ou outro objeto não localizado.

Possíveis causas:

  • nome incorreto;

  • qualifier incorreto;

  • objeto inexistente;

  • ambiente incorreto;

  • uso de tabela de desenvolvimento em produção ou vice-versa.


SQLCODE -206

Coluna não encontrada ou inválida no contexto.

Possíveis causas:

  • nome digitado incorretamente;

  • coluna removida;

  • alias de tabela ausente;

  • SQL desatualizado em relação à estrutura do banco.


SQLCODE -551

Problema de autorização.

O usuário ou authid não possui privilégio suficiente para realizar a operação.

O programa pode estar perfeito.

O BIND pode existir.

A tabela pode existir.

Mas a porta permanece trancada.


SQLCODE +100

Nenhuma linha encontrada.

Não é necessariamente um erro.

Em um SELECT INTO, pode significar que nenhum registro correspondeu à condição.

Em um cursor, pode indicar fim das linhas.

O erro verdadeiro é tratar +100 como se nunca pudesse acontecer.


19. JCL conceitual do processo

Um JCL real varia muito entre instalações, mas conceitualmente o processo pode ter steps como:

STEP 1 - Pré-compilação Db2
STEP 2 - Compilação COBOL
STEP 3 - Link-edit
STEP 4 - BIND PACKAGE
STEP 5 - BIND PLAN, quando necessário

Ou, em outra organização:

STEP 1 - Compilação com SQL coprocessor
STEP 2 - Link-edit
STEP 3 - BIND PACKAGE

Pipelines modernos podem executar essas etapas por meio de:

  • JCLs padronizados;

  • procedures catalogadas;

  • Endevor;

  • ISPW;

  • DBB;

  • Jenkins;

  • Git;

  • scripts de automação;

  • ferramentas DevOps para IBM Z.

Mesmo que o programador clique em um botão chamado “Build”, o botão não faz magia.

Ele apenas dispara uma sequência semelhante à investigação que acabamos de seguir.


20. A ordem das etapas importa

Imagine que o programa tenha sido alterado.

O desenvolvedor adiciona uma coluna ao SELECT:

SELECT NOME_CLIENTE,
       SALDO_CONTA,
       LIMITE_CREDITO

O fonte é pré-processado e compilado.

O novo load module é promovido.

Mas o novo DBRM não é utilizado no BIND.

O resultado é um executável novo tentando conversar com um PACKAGE antigo.

Isso pode gerar incompatibilidade.

Agora imagine o contrário:

O PACKAGE novo é bindado, mas o load module antigo permanece na biblioteca de produção.

Mais uma vez, versões diferentes se encontram.

Por isso, uma promoção correta precisa tratar como uma unidade:

Fonte
DBRM
Load module
PACKAGE
Configuração de execução

Em ambientes controlados, o processo de change management deve garantir que todas as peças da mesma versão avancem juntas.


21. O que acontece em tempo de execução

Quando o programa é executado, o z/OS carrega o load module.

Ao alcançar uma instrução SQL, a lógica gerada durante o pré-processamento encaminha a solicitação ao Db2.

O Db2 identifica:

  • o subsistema;

  • o plano ou contexto de execução;

  • a collection;

  • o PACKAGE;

  • a seção SQL correspondente.

Depois, executa o access path registrado ou reavaliado conforme as características do ambiente e as opções utilizadas.

O resultado é devolvido às host variables.

O SQLCODE é atualizado.

O programa COBOL continua.

Fluxo simplificado:

Programa COBOL executando
          |
          v
Encontra instrução SQL
          |
          v
Interface com Db2
          |
          v
Localiza PACKAGE
          |
          v
Executa SQL
          |
          v
Acessa tabela ou índice
          |
          v
Retorna dados e SQLCODE
          |
          v
Programa COBOL prossegue

Para o usuário, tudo isso pode acontecer em milésimos de segundo.

Para o programador, são décadas de engenharia condensadas em um único EXEC SQL.


22. Compile não é BIND

Uma das confusões mais comuns entre iniciantes é pensar:

O programa compilou, então o SQL está correto.

Nem sempre.

A compilação COBOL valida o código COBOL e as estruturas geradas.

O BIND é que realiza boa parte da validação relacionada ao Db2.

Dependendo das opções usadas, alguns problemas só aparecerão durante o BIND ou até durante a execução.

Portanto:

Compilação bem-sucedida
não garante
BIND bem-sucedido.

E:

BIND bem-sucedido
não garante
execução funcionalmente correta.

Um SELECT pode executar perfeitamente e devolver o cliente errado porque a regra de negócio foi escrita de maneira incorreta.

Nenhum compilador consegue condenar uma lógica que é sintaticamente válida, mas conceitualmente equivocada.


23. BIND não é apenas burocracia

É comum enxergar o BIND apenas como uma etapa obrigatória.

Mas ele também está ligado à performance.

Durante o BIND ou REBIND, o Db2 pode determinar access paths com base em informações como:

  • índices disponíveis;

  • estatísticas de tabelas;

  • estatísticas de colunas;

  • cardinalidade;

  • distribuição dos dados;

  • custo estimado;

  • métodos de join;

  • quantidade de páginas;

  • seletividade dos predicados.

Se as estatísticas estiverem desatualizadas, o Db2 poderá tomar decisões baseadas em uma fotografia antiga da cena.

É por isso que operações como RUNSTATS possuem tanta importância.

O otimizador só pode investigar com as evidências que recebe.


24. REBIND

O REBIND permite reconstruir informações de um PACKAGE existente sem necessariamente recompilar o programa COBOL.

Ele pode ser utilizado quando:

  • estatísticas foram atualizadas;

  • índices foram criados ou alterados;

  • ocorreu mudança de versão;

  • deseja-se recalcular access paths;

  • políticas de performance exigem revisão;

  • objetos sofreram alterações.

Mas um REBIND deve ser tratado com cuidado.

Um novo access path pode melhorar a performance.

Também pode piorá-la.

Em ambientes críticos, equipes analisam EXPLAIN, histórico de access paths e comportamento anterior antes de aceitar mudanças.

Todo bom detetive sabe que reabrir um caso pode revelar a verdade.

Mas também pode destruir uma pista que ainda era útil.


25. COLLECTION, PACKAGE e versão

Packages podem ser organizados em collections.

Isso permite separar ambientes ou versões.

Exemplo conceitual:

Collection: DESENV
Package: PROGCLI1

Collection: HOMOLOG
Package: PROGCLI1

Collection: PRODUCAO
Package: PROGCLI1

O nome do programa pode ser o mesmo.

Mas cada collection representa um contexto diferente.

Também podem existir estratégias de versionamento:

PROGCLI1 versão V1
PROGCLI1 versão V2

Esses mecanismos ajudam em:

  • implantação;

  • rollback;

  • testes paralelos;

  • manutenção;

  • coexistência de versões.

Entretanto, quanto maior a flexibilidade, maior a necessidade de controle.

Sem governança, uma collection se transforma em uma rua escura cheia de packages com identidades falsas.


26. Static SQL e Dynamic SQL

O fluxo descrito é principalmente associado ao SQL estático.

No SQL estático, a instrução é conhecida antes da execução:

EXEC SQL
    SELECT NOME_CLIENTE
      INTO :WS-NOME
      FROM CLIENTES
     WHERE COD_CLIENTE = :WS-COD
END-EXEC.

No SQL dinâmico, o texto da instrução pode ser montado durante a execução.

Exemplo conceitual:

MOVE 'SELECT NOME_CLIENTE FROM CLIENTES'
  TO WS-COMANDO-SQL.

Depois, o programa pode usar comandos como:

PREPARE
EXECUTE
OPEN

O SQL dinâmico oferece flexibilidade.

Mas pode aumentar a complexidade relacionada a:

  • segurança;

  • autorização;

  • performance;

  • cache;

  • validação;

  • construção de comandos;

  • risco de SQL injection, quando entradas são tratadas incorretamente.

O SQL estático é como uma operação planejada.

O SQL dinâmico é como receber uma missão enquanto o carro já está em movimento.


27. O papel do programador COBOL

O programador COBOL–Db2 precisa enxergar além do fonte.

Ele deve saber responder:

  • Qual pré-processador está sendo usado?

  • Onde o DBRM é gerado?

  • Em qual biblioteca o load module é gravado?

  • Qual collection contém o PACKAGE?

  • Qual PLAN ou PKLIST participa da execução?

  • Qual subsistema Db2 será acessado?

  • Qual qualifier está sendo utilizado?

  • Qual authid realiza o BIND?

  • Quem executa o programa?

  • Qual é o nível de isolamento?

  • O programa verifica SQLCODE?

  • Existem colunas nullable?

  • As host variables são compatíveis?

  • O BIND acompanha a promoção do load module?

Essas perguntas separam o programador que apenas altera linhas daquele que compreende o ciclo de vida da aplicação.


28. Checklist para o iniciante

Antes de declarar o caso encerrado, verifique:

[ ] O fonte COBOL está correto?

[ ] Todas as instruções EXEC SQL possuem END-EXEC?

[ ] As host variables estão declaradas?

[ ] Os tipos COBOL combinam com as colunas Db2?

[ ] Colunas nullable possuem indicator variables?

[ ] A SQLCA foi incluída?

[ ] O programa testa SQLCODE?

[ ] O pré-processamento terminou corretamente?

[ ] O DBRM foi gerado?

[ ] A compilação COBOL terminou sem erros?

[ ] O link-edit criou o load module?

[ ] O BIND PACKAGE foi executado?

[ ] A collection está correta?

[ ] O PLAN ou PKLIST encontra o PACKAGE?

[ ] O executável e o PACKAGE pertencem à mesma versão?

[ ] O usuário possui autorização?

[ ] A load library correta está sendo utilizada?

[ ] O subsistema Db2 correto está ativo?

Esse checklist não evita todos os crimes.

Mas reduz bastante o número de suspeitos.


29. O fluxo resumido em uma frase

Um programa COBOL com Db2 passa pelo pré-processamento para separar COBOL e SQL, pela compilação para gerar o código objeto, pelo link-edit para criar o executável e pelo BIND para transformar o SQL estático em um PACKAGE reconhecido pelo Db2.

Ou, em linguagem de rua:

O pré-compilador separa.
O compilador traduz.
O Binder monta.
O BIND registra.
O Db2 executa.

30. Conclusão: dois caminhos, uma única execução

Às 3h12 da manhã, o caso finalmente estava resolvido.

O programa não era apenas COBOL.

Também não era apenas SQL.

Ele era uma aliança entre dois mundos.

O lado COBOL cuidava da lógica, dos campos, dos arquivos, dos cálculos e das decisões.

O lado Db2 cuidava das tabelas, dos índices, dos access paths, dos locks e da persistência dos dados.

Entre os dois, o pré-compilador atuava como intérprete.

O DBRM carregava o depoimento das instruções SQL.

O compilador transformava COBOL em código objeto.

O Binder criava o módulo executável.

O BIND registrava o PACKAGE no submundo do Db2.

Na execução, todas essas peças precisavam apresentar os mesmos documentos.

Quando tudo correspondia, o SELECT retornava seus dados e o programa continuava tranquilamente.

Quando alguma peça pertencia à versão errada, surgiam os suspeitos habituais:

-805
-818
-204
-206
-551

Apaguei a última luz do CPD e deixei o programa executando.

Lá fora, a chuva ainda caía.

Dentro do mainframe, milhões de instruções SQL atravessavam o mesmo caminho sem que ninguém percebesse.

Porque esta é uma das grandes verdades do IBM Z:

quando o fluxo de compilação funciona, ninguém nota.

Mas quando o BIND desaparece, o DBRM não combina ou o PACKAGE está na collection errada, sempre haverá um programador COBOL caminhando pelos corredores da madrugada, seguindo as pistas deixadas no spool.

E pedindo mais um café.

Posso também transformar esse conteúdo em uma versão ampliada com JCL completo de pré-compilação, compilação, link-edit e BIND PACKAGE.




Infografico demonstrando o fluxo de compilação de um programa mainframe COBOL com acesso ao Banco de Dados DB2. 

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