1. O que é IMS e por que ainda existe

IMS é um sistema de gerenciamento de banco de dados hierárquico da IBM que roda exclusivamente em z/OS (mainframe). Foi o primeiro banco de dados comercial de larga escala, projetado quando o conceito de banco de dados relacional nem existia — o paper fundador de Codd sobre o modelo relacional foi publicado em 1970, quatro anos depois do IMS.

🦕 Por que o IMS sobreviveu ao relacional?
Porque os sistemas construídos sobre ele nos anos 70 e 80 ficaram tão grandes e críticos que a migração nunca valeu o risco. Um banco que processa 10 bilhões de transações por dia não para para migrar de banco de dados. O IMS tem performance comprovada por décadas, zero downtime planejado e capacidade de processar mais de 1 bilhão de transações por dia por instância. Em muitos cenários de acesso hierárquico previsível, IMS ainda é mais rápido que SQL.

Alguns números que contextualizam a relevância do IMS hoje:

DadoNúmero
Bancos entre os 50 maiores do mundo que usam IMS95%+
Transações IMS processadas por dia no mundo50 bilhões+
Ano de criação1966 (IBM + Rockwell + Caterpillar para NASA)
Versão atualIMS 15 (z/OS)
Tipo de acessoDL/I (Data Language/Interface) — chamadas procedurais

2. Modelo hierárquico vs relacional

No modelo relacional (DB2, Oracle, SQL Server), os dados ficam em tabelas planas relacionadas por chaves estrangeiras. Você usa SQL para navegar entre tabelas com JOINs. No modelo hierárquico do IMS, os dados ficam organizados em árvores — cada nó é um segmento, e a relação entre segmentos é sempre pai-filho, definida em tempo de design.

Modelo relacional — tabelas com JOIN
TABELA CLIENTE          TABELA CONTA
-----------             -----------
CLI_CPF (PK)            CONTA_NUM (PK)
CLI_NOME                CONTA_CLI_CPF (FK)
CLI_ENDERECO            CONTA_SALDO

SELECT C.CLI_NOME, A.CONTA_SALDO
  FROM CLIENTE C
  JOIN CONTA A ON A.CONTA_CLI_CPF = C.CLI_CPF
 WHERE C.CLI_CPF = '12345678901'
Modelo hierárquico IMS — árvore de segmentos
CLIENTE (segmento raiz)
├── CPF: 12345678901
├── NOME: MARIA SILVA
└── CONTA (segmento filho)
    ├── NUM: 001234-5
    ├── SALDO: 15000.00
    └── MOVIMENTO (segmento neto)
        ├── DATA: 20260610
        └── VALOR: -500.00
AspectoIMS (Hierárquico)DB2 (Relacional)
Estrutura Árvore — pai e filhos Tabelas planas
Relacionamento Definido no schema (DBD) — fixo Definido na query (JOIN) — dinâmico
Linguagem de acesso DL/I calls (GU, GN, ISRT...) SQL (SELECT, INSERT, UPDATE...)
Navegação Procedural — você move um "cursor" pela árvore Declarativa — você descreve o resultado
Performance em hierarquia Excelente — dados físicamente próximos Boa — JOIN pode ser custoso em volumes altos
Flexibilidade ad-hoc Baixa — hierarquia definida previamente Alta — qualquer JOIN possível

3. Segmentos — a unidade básica do IMS

Um segmento é o equivalente IMS de uma linha de tabela — é a menor unidade de dados que o IMS lê ou escreve por vez. Cada segmento tem:

  • Um nome (até 8 caracteres) — ex: CLIENTE, CONTA, MOVIMENT
  • Um comprimento fixo ou variável em bytes
  • Um ou mais fields (campos) — equivalente a colunas
  • Opcionalmente, uma chave de sequência (sequence field) que define a ordem dos segmentos do mesmo tipo
COBOL — estrutura de um segmento IMS
      *    Segmento CLIENTE (80 bytes)
       01  WS-SEG-CLIENTE.
           05 CLI-CPF        PIC 9(11).
           05 CLI-NOME       PIC X(40).
           05 CLI-NASC       PIC 9(08).
           05 CLI-TIPO       PIC X(01).
           05 FILLER         PIC X(20).

      *    Segmento CONTA (60 bytes)
       01  WS-SEG-CONTA.
           05 CTR-NUM        PIC X(10).
           05 CTR-TIPO       PIC X(02).
           05 CTR-SALDO      PIC S9(13)V99 COMP-3.
           05 CTR-LIMITE     PIC S9(13)V99 COMP-3.
           05 CTR-STATUS     PIC X(01).
           05 FILLER         PIC X(13).
✅ Segmento vs registro VSAM
Um segmento IMS é conceitualmente parecido com um registro VSAM — ambos são estruturas de bytes com campos definidos no programa COBOL. A diferença é que o IMS gerencia o relacionamento entre segmentos (hierarquia pai-filho) automaticamente, enquanto no VSAM você precisa implementar esse relacionamento na aplicação.

4. Hierarquia — pai, filho e gêmeos

A estrutura do banco IMS é uma árvore com terminologia específica:

Terminologia da hierarquia IMS
CLIENTE  ← Segmento RAIZ (root) — primeiro nível, sem pai
│           Sequence field: CPF (ordena clientes por CPF)
│
├── CONTA  ← Segmento filho de CLIENTE — segundo nível
│   │        Sequence field: NUM-CONTA
│   │
│   └── MOVIMENT  ← Segmento filho de CONTA — terceiro nível
│                   Sequence field: DATA-MOV
│
└── ENDERECO  ← Outro filho de CLIENTE (irmão de CONTA)
                Sem sequence field (ordem de inserção)

GÊMEOS (twins): dois ou mais segmentos do mesmo tipo
com o mesmo pai. Ex: um cliente pode ter múltiplas CONTAs.
Cada CONTA de um mesmo CLIENTE é um "twin" das demais.
Termo IMSSignificado
Root segmentSegmento de primeiro nível — não tem pai. Todo acesso começa aqui.
Dependent segmentQualquer segmento que tem pai — está "dependente" de um segmento pai.
ParentSegmento imediatamente acima na hierarquia.
ChildSegmento imediatamente abaixo — dependente direto do pai.
TwinDois ou mais segmentos do mesmo tipo com o mesmo pai. Ex: duas contas do mesmo cliente.
SiblingSegmentos de tipos diferentes com o mesmo pai. Ex: CONTA e ENDERECO são siblings.
Sequence fieldCampo-chave que define a ordem dos twins dentro de um pai. Equivale à chave primária.
OccurrenceUma instância específica de um segmento. Ex: a conta 001234-5 é uma occurrence do tipo CONTA.
💗 Entendendo gêmeos (twins)
Imagine um cliente com três contas: corrente, poupança e investimento. No IMS, existem três segmentos CONTA "gêmeos" — todos filhos do mesmo segmento CLIENTE. Para ler todas as contas de um cliente, você faz uma GU (Get Unique) no cliente e depois GNP (Get Next within Parent) para varrer os gêmeos CONTA, um a um, até acabar.

5. DBD — Database Description

O DBD (Database Description) é o schema do banco IMS — define quais segmentos existem, em que ordem hierárquica estão, quais campos têm, e como o banco é fisicamente organizado no disco. O DBD é criado pelo DBA usando macros assembler e compilado pelo utilitário DBDGEN.

DBD — exemplo de banco de clientes e contas
         DBD    NAME=BANCOCLI,ACCESS=HDAM
*
* Segmento raiz: CLIENTE
*
         SEGM   NAME=CLIENTE,BYTES=80,PARENT=0
         FIELD  NAME=(CLICPF,SEQ,U),BYTES=11,START=1,TYPE=P
         FIELD  NAME=CLINOME,BYTES=40,START=12,TYPE=C
         FIELD  NAME=CLINASC,BYTES=8,START=52,TYPE=P
         FIELD  NAME=CLITIPO,BYTES=1,START=60,TYPE=C
*
* Segmento filho: CONTA (filho de CLIENTE)
*
         SEGM   NAME=CONTA,BYTES=60,PARENT=CLIENTE
         FIELD  NAME=(CTANUM,SEQ,U),BYTES=10,START=1,TYPE=C
         FIELD  NAME=CTATIPO,BYTES=2,START=11,TYPE=C
         FIELD  NAME=CTASLDO,BYTES=8,START=13,TYPE=P
         FIELD  NAME=CTASTTS,BYTES=1,START=29,TYPE=C
*
* Segmento neto: MOVIMENT (filho de CONTA)
*
         SEGM   NAME=MOVIMENT,BYTES=30,PARENT=CONTA
         FIELD  NAME=(MOVDATA,SEQ),BYTES=8,START=1,TYPE=P
         FIELD  NAME=MOVVALOR,BYTES=8,START=9,TYPE=P
         FIELD  NAME=MOVTIPO,BYTES=1,START=17,TYPE=C
*
         DBDGEN
         FINISH
         END

Atributos de campo no DBD

AtributoValoresSignificado
SEQPresente ou ausenteMarca o campo como sequence field (chave de ordenação dos twins)
U / MU = unique, M = multipleU: sequence field único (sem twins com mesmo valor). M: duplicatas permitidas.
TYPEC, P, X, ZC = character, P = packed decimal, X = hex, Z = zoned decimal
BYTESNúmeroComprimento do campo em bytes
STARTNúmeroPosição inicial dentro do segmento (começa em 1)
🟣 O programador COBOL raramente escreve DBD
DBD é responsabilidade do DBA de IMS. O programador recebe o DBD já compilado (em forma de ACB — Application Control Block) e trabalha com o PSB/PCB que descreve o que o programa pode ver e fazer no banco. Mas entender a estrutura do DBD é essencial para interpretar erros, planejar queries e discutir mudanças de schema com o DBA.

6. PSB e PCB — como o programa enxerga o banco

Um programa COBOL não acessa o DBD diretamente. Entre o programa e o banco existem duas estruturas intermediárias: o PSB e o PCB.

PSB — Program Specification Block

O PSB é a "visão" do programa sobre o banco — define quais segmentos o programa pode acessar e com quais permissões. É criado pelo DBA e compilado pelo utilitário PSBGEN.

PSB — exemplo para programa de consulta de contas
         PCB    TYPE=DB,DBDNAME=BANCOCLI,KEYLEN=21,
                PROCOPT=G
         SENSEG NAME=CLIENTE,PROCOPT=G
         SENSEG NAME=CONTA,PROCOPT=G
         SENSEG NAME=MOVIMENT,PROCOPT=G
         PSBGEN LANG=COBOL,PSBNAME=PGMCONTA
         END

PROCOPT controla o que o programa pode fazer com cada segmento:

PROCOPTOperações permitidas
GGet only — apenas leitura (GU, GN, GNP)
IInsert only — apenas inserção (ISRT)
DDelete only — apenas deleção (DLET)
RReplace only — apenas atualização (REPL)
AAll — todas as operações (G + I + D + R)
GOGet with hold — leitura com lock para atualização posterior

PCB — Program Communication Block

O PCB é a estrutura em memória que o IMS popula a cada DL/I call — contém o status da última operação, a chave do segmento acessado e informações de erro. O programa COBOL declara o PCB na LINKAGE SECTION e o recebe no ENTRY.

COBOL — declaração do PCB na LINKAGE SECTION
       LINKAGE SECTION.
      *    PCB do banco BANCOCLI
       01  PCB-BANCO.
           05 PCB-DBD-NAME   PIC X(08).
           05 PCB-SEG-LEVEL  PIC XX.
           05 PCB-STATUS     PIC XX.
           05 PCB-PROC-OPT   PIC X(04).
           05 FILLER         PIC X(04).
           05 PCB-SEG-NAME   PIC X(08).
           05 PCB-KEY-LENGTH PIC S9(05) COMP.
           05 PCB-NUMB-SENS  PIC S9(05) COMP.
           05 PCB-KEY-CONCAT PIC X(21).

       PROCEDURE DIVISION.
           ENTRY 'DLITCBL' USING PCB-BANCO.

O campo mais importante do PCB é o PCB-STATUS: dois caracteres que indicam o resultado da última DL/I call.

PCB-STATUSSignificado
bb (dois brancos)Sucesso — operação completou normalmente
GESegment Not Found — segmento não encontrado (equivale ao NOT FOUND do SQL)
GBEnd of Database — fim do banco (em leitura sequencial)
GKGet Next no longer within parent — saiu dos filhos do pai atual
IIInsert: sequence field duplicado (quando PROCOPT SEQ=U)
DJDelete: segmento tem filhos — não pode deletar
AIISRT sem SSA válido — posicionamento incorreto
🦕 PCB-STATUS é o FILE STATUS do IMS
Assim como o FILE STATUS do COBOL diz o que aconteceu na última operação de arquivo VSAM (00 = ok, 23 = not found), o PCB-STATUS diz o que aconteceu na última DL/I call. Espaços em branco = sucesso. GE = não encontrou. GB = acabou o banco. Todo programa IMS verifica PCB-STATUS após cada call.

7. IMS DB vs IMS DC

IMS tem dois subsistemas principais que podem rodar juntos ou separados:

SubsistemaNome completoFunção
IMS DB IMS Database Manager Gerencia os bancos de dados hierárquicos — HDAM, HIDAM, HISAM, HSAM. É o "banco" propriamente dito.
IMS DC IMS Data Communications Gerencia transações online — recebe mensagens de terminais 3270, despacha para programas (MPP), retorna respostas. É o equivalente IMS do CICS.
Tipos de programa IMS por ambiente
IMS DB (batch):
  └── DL/I batch program — roda via JCL, usa IMS DB diretamente

IMS DC (online):
  ├── MPP (Message Processing Program) — processa uma mensagem,
  │   retorna resposta, termina (pseudo-conversacional como CICS)
  ├── BMP (Batch Message Processing) — acessa IMS DB e DC
  │   em modo batch com checkpoints
  └── JBP (Java Batch Processing) — variante Java do BMP

No dia a dia, a maioria dos programadores COBOL que trabalha com IMS opera no modo IMS DB batch (programas que rodam como jobs JCL e acessam bancos hierárquicos) ou como BMP (batch que também pode enviar/receber mensagens IMS DC).

8. Tipos de banco IMS — HDAM, HIDAM, HISAM, HSAM

O tipo de banco IMS define como os segmentos são armazenados fisicamente no VSAM. Cada tipo tem características de performance diferentes:

TipoNome completoAcessoDataset VSAMUso típico
HDAM Hierarchical Direct Access Method Direto por hash + sequencial ESDS (data) + ESDS (overflow) Acesso aleatório por root — mais comum em produção
HIDAM Hierarchical Indexed Direct Access Method Direto por índice B+ + sequencial KSDS (index) + ESDS (data) Quando a ordem sequencial da chave importa
HISAM Hierarchical Indexed Sequential Access Method Sequencial por chave KSDS (principal) + ESDS (overflow) Bancos pequenos, acesso predominantemente sequencial
HSAM Hierarchical Sequential Access Method Sequencial apenas Dataset sequencial (QSAM) Tape ou datasets de arquivo — raramente usado hoje
✅ HDAM é o mais comum
Em ambientes bancários de produção, HDAM domina. O root segment é localizado via função de randomização (hash do sequence field) que calcula diretamente o bloco DASD onde o segmento está — sem percorrer um índice. O resultado é acesso em tempo quase constante para qualquer root, independente do tamanho do banco.

9. Primeira DL/I call — visão geral

As DL/I calls são a linguagem de acesso ao IMS — equivalem ao SQL mas são chamadas procedurais. O programa COBOL usa a instrução CALL 'CBLTDLI' para invocar o IMS.

COBOL — estrutura geral de uma DL/I call
       CALL 'CBLTDLI' USING
           WS-NUMERO-SSAS      (quantos SSAs na chamada)
           WS-FUNCAO           (GU, GN, GNP, ISRT, DLET, REPL)
           PCB-BANCO           (PCB do banco a acessar)
           WS-SEG-CLIENTE      (área de dados do segmento)
           WS-SSA-CLIENTE      (SSA — critério de qualificação)

As 6 funções DL/I principais

FunçãoNome completoO que faz
GUGet UniqueBusca direta por qualificação — equivale ao SELECT com WHERE
GNGet NextPróximo segmento em ordem hierárquica — leitura sequencial
GNPGet Next within ParentPróximo segmento filho do pai atual — varre gêmeos
GHUGet Hold UniqueGU com lock — obrigatório antes de DLET ou REPL
GHNGet Hold NextGN com lock — obrigatório antes de DLET ou REPL
GHNPGet Hold Next within ParentGNP com lock — para atualizar gêmeos em sequência
ISRTInsertInsere um novo segmento no banco
DLETDeleteDeleta o segmento em hold (após GHU/GHN/GHNP)
REPLReplaceAtualiza o segmento em hold com o conteúdo da área de dados
COBOL — leitura de cliente por CPF (GU com SSA qualificado)
       WORKING-STORAGE SECTION.
       01  WS-FUNC-GU    PIC X(04) VALUE 'GU  '.
       01  WS-NUM-SSAS   PIC S9(05) COMP VALUE 1.

      *    SSA qualificado para buscar cliente por CPF
       01  WS-SSA-CLI.
           05 FILLER     PIC X(08) VALUE 'CLIENTE '.
           05 FILLER     PIC X(01) VALUE '('.
           05 FILLER     PIC X(08) VALUE 'CLICPF  '.
           05 FILLER     PIC X(02) VALUE '= '.
           05 SSA-CLI-CPF PIC 9(11).
           05 FILLER     PIC X(01) VALUE ')'.

       PROCEDURE DIVISION.
       1000-BUSCA-CLIENTE.
           MOVE '12345678901' TO SSA-CLI-CPF
           CALL 'CBLTDLI' USING
               WS-NUM-SSAS
               WS-FUNC-GU
               PCB-BANCO
               WS-SEG-CLIENTE
               WS-SSA-CLI
           EVALUATE PCB-STATUS
               WHEN SPACES
                   DISPLAY 'CLIENTE: ' CLI-NOME
               WHEN 'GE'
                   DISPLAY 'CLIENTE NAO ENCONTRADO'
               WHEN OTHER
                   DISPLAY 'ERRO IMS: ' PCB-STATUS
           END-EVALUATE.

10. IMS no mundo real — sistemas bancários

No contexto bancário, o IMS aparece em sistemas centrais que existem desde os anos 70 e 80 e foram crescendo em cima da estrutura original. As hierarquias típicas são:

Hierarquias típicas em bancos brasileiros
Banco de Clientes:
CLIENTE
  ├── ENDERECO (endereços do cliente)
  ├── CONTA (contas bancárias)
  │     └── MOVIMENT (movimentações da conta)
  ├── PROPOSTA (propostas de crédito)
  │     └── PARCELA (parcelas do empréstimo)
  └── LIMITE (limites por produto)

Banco de Operações:
AGENCIA
  ├── OPERADOR (funcionários da agência)
  └── CAIXA (caixas eletrônicos)
        └── TRANSACAO (transações do caixa)
💗 O que esperar no próximo artigo
No artigo 02 você vai escrever programas COBOL reais com todas as DL/I calls: GU para buscar um cliente por CPF, GNP para varrer todas as contas de um cliente, GHU + REPL para atualizar saldo, GHU + DLET para excluir uma proposta e ISRT para inserir um novo movimento. Você vai ver a sintaxe completa, os SSAs e como verificar cada status code.

JCL para rodar um programa IMS DB batch

JCL — execução de programa IMS batch
//IMSBATCH JOB (ACCT),'IMS BATCH',CLASS=A,MSGCLASS=X
//STEP1    EXEC PGM=DFSRRC00,
//             PARM='DLI,MEUPROG,BANCOCLIP,,,,,,,,,,Y,N'
//STEPLIB  DD DSN=IMS.RESLIB,DISP=SHR
//         DD DSN=PROD.LOADLIB,DISP=SHR
//DFSRESLB DD DSN=IMS.RESLIB,DISP=SHR
//IMS      DD DSN=IMS.PSBLIB,DISP=SHR
//         DD DSN=IMS.DBDLIB,DISP=SHR
//IEFRDER  DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//DFSVSAMP DD DSN=IMS.PROCLIB(DFSVSMHP),DISP=SHR

O programa DFSRRC00 é o region controller do IMS — ele inicializa o ambiente IMS, carrega o PSB do programa (BANCOCLIP) e invoca o programa COBOL. O programador não precisa escrever esse JCL do zero — cada instalação tem um PROC catalogado para isso.