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.
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:
| Dado | Número |
|---|---|
| Bancos entre os 50 maiores do mundo que usam IMS | 95%+ |
| Transações IMS processadas por dia no mundo | 50 bilhões+ |
| Ano de criação | 1966 (IBM + Rockwell + Caterpillar para NASA) |
| Versão atual | IMS 15 (z/OS) |
| Tipo de acesso | DL/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.
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'
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
| Aspecto | IMS (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
* 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).
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:
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 IMS | Significado |
|---|---|
| Root segment | Segmento de primeiro nível — não tem pai. Todo acesso começa aqui. |
| Dependent segment | Qualquer segmento que tem pai — está "dependente" de um segmento pai. |
| Parent | Segmento imediatamente acima na hierarquia. |
| Child | Segmento imediatamente abaixo — dependente direto do pai. |
| Twin | Dois ou mais segmentos do mesmo tipo com o mesmo pai. Ex: duas contas do mesmo cliente. |
| Sibling | Segmentos de tipos diferentes com o mesmo pai. Ex: CONTA e ENDERECO são siblings. |
| Sequence field | Campo-chave que define a ordem dos twins dentro de um pai. Equivale à chave primária. |
| Occurrence | Uma instância específica de um segmento. Ex: a conta 001234-5 é uma occurrence do tipo CONTA. |
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 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
| Atributo | Valores | Significado |
|---|---|---|
| SEQ | Presente ou ausente | Marca o campo como sequence field (chave de ordenação dos twins) |
| U / M | U = unique, M = multiple | U: sequence field único (sem twins com mesmo valor). M: duplicatas permitidas. |
| TYPE | C, P, X, Z | C = character, P = packed decimal, X = hex, Z = zoned decimal |
| BYTES | Número | Comprimento do campo em bytes |
| START | Número | Posição inicial dentro do segmento (começa em 1) |
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.
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:
| PROCOPT | Operações permitidas |
|---|---|
| G | Get only — apenas leitura (GU, GN, GNP) |
| I | Insert only — apenas inserção (ISRT) |
| D | Delete only — apenas deleção (DLET) |
| R | Replace only — apenas atualização (REPL) |
| A | All — todas as operações (G + I + D + R) |
| GO | Get 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.
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-STATUS | Significado |
|---|---|
| bb (dois brancos) | Sucesso — operação completou normalmente |
| GE | Segment Not Found — segmento não encontrado (equivale ao NOT FOUND do SQL) |
| GB | End of Database — fim do banco (em leitura sequencial) |
| GK | Get Next no longer within parent — saiu dos filhos do pai atual |
| II | Insert: sequence field duplicado (quando PROCOPT SEQ=U) |
| DJ | Delete: segmento tem filhos — não pode deletar |
| AI | ISRT sem SSA válido — posicionamento incorreto |
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:
| Subsistema | Nome completo | Funçã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. |
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:
| Tipo | Nome completo | Acesso | Dataset VSAM | Uso 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 |
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.
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ção | Nome completo | O que faz |
|---|---|---|
| GU | Get Unique | Busca direta por qualificação — equivale ao SELECT com WHERE |
| GN | Get Next | Próximo segmento em ordem hierárquica — leitura sequencial |
| GNP | Get Next within Parent | Próximo segmento filho do pai atual — varre gêmeos |
| GHU | Get Hold Unique | GU com lock — obrigatório antes de DLET ou REPL |
| GHN | Get Hold Next | GN com lock — obrigatório antes de DLET ou REPL |
| GHNP | Get Hold Next within Parent | GNP com lock — para atualizar gêmeos em sequência |
| ISRT | Insert | Insere um novo segmento no banco |
| DLET | Delete | Deleta o segmento em hold (após GHU/GHN/GHNP) |
| REPL | Replace | Atualiza o segmento em hold com o conteúdo da área de dados |
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:
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)
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
//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.