1. Estrutura de um programa IMS COBOL
Um programa COBOL que acessa IMS tem diferenças importantes em relação a um programa batch comum:
IDENTIFICATION DIVISION.
PROGRAM-ID. PGMCONTA.
ENVIRONMENT DIVISION.
* Sem FILE-CONTROL para IMS — acesso é via CALL, não via SELECT
DATA DIVISION.
WORKING-STORAGE SECTION.
* ── Funções DL/I ─────────────────────────────────────────────
01 WS-FUNC-GU PIC X(04) VALUE 'GU '.
01 WS-FUNC-GN PIC X(04) VALUE 'GN '.
01 WS-FUNC-GNP PIC X(04) VALUE 'GNP '.
01 WS-FUNC-GHU PIC X(04) VALUE 'GHU '.
01 WS-FUNC-GHN PIC X(04) VALUE 'GHN '.
01 WS-FUNC-GHNP PIC X(04) VALUE 'GHNP'.
01 WS-FUNC-ISRT PIC X(04) VALUE 'ISRT'.
01 WS-FUNC-DLET PIC X(04) VALUE 'DLET'.
01 WS-FUNC-REPL PIC X(04) VALUE 'REPL'.
* ── Contadores de SSA ─────────────────────────────────────────
01 WS-SSA-1 PIC S9(05) COMP VALUE 1.
01 WS-SSA-2 PIC S9(05) COMP VALUE 2.
01 WS-SSA-3 PIC S9(05) COMP VALUE 3.
* ── Área de dados dos segmentos ───────────────────────────────
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).
01 WS-SEG-CONTA.
05 CTA-NUM PIC X(10).
05 CTA-TIPO PIC X(02).
05 CTA-SALDO PIC S9(13)V99 COMP-3.
05 CTA-STATUS PIC X(01).
05 FILLER PIC X(13).
* ── SSAs ──────────────────────────────────────────────────────
01 WS-SSA-CLI-UNQUAL.
05 FILLER PIC X(09) VALUE 'CLIENTE '.
01 WS-SSA-CLI-QUAL.
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 ')'.
01 WS-SSA-CTA-UNQUAL.
05 FILLER PIC X(09) VALUE 'CONTA '.
01 WS-SSA-CTA-QUAL.
05 FILLER PIC X(08) VALUE 'CONTA '.
05 FILLER PIC X(01) VALUE '('.
05 FILLER PIC X(08) VALUE 'CTANUM '.
05 FILLER PIC X(02) VALUE '= '.
05 SSA-CTA-NUM PIC X(10).
05 FILLER PIC X(01) VALUE ')'.
LINKAGE SECTION.
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-LEN PIC S9(05) COMP.
05 PCB-NUMB-SENS PIC S9(05) COMP.
05 PCB-KEY-FDBK PIC X(21).
PROCEDURE DIVISION.
ENTRY 'DLITCBL' USING PCB-BANCO.
0000-PRINCIPAL.
PERFORM 1000-BUSCA-CLIENTE
PERFORM 2000-VARRE-CONTAS
GOBACK.
Programas IMS não usam STOP RUN — usam GOBACK. O ponto de entrada é sempre
ENTRY 'DLITCBL' USING seguido dos PCBs na ordem definida no PSB. Se o PSB tem dois PCBs (ex: um de banco e um IOPCB para mensagens), ambos devem aparecer no USING.
2. Sintaxe da CALL CBLTDLI
Toda DL/I call segue o mesmo padrão de parâmetros:
CALL 'CBLTDLI' USING
WS-NUM-SSAS (1) número de SSAs — PIC S9(05) COMP
WS-FUNC-XX (2) função — GU, GN, GNP, ISRT, DLET, REPL
PCB-BANCO (3) PCB do banco a ser acessado
WS-SEG-XXXXXX (4) área de dados do segmento (I/O)
WS-SSA-1 (5) primeiro SSA — opcional
WS-SSA-2 (6) segundo SSA — opcional
WS-SSA-N (N) N-ésimo SSA — opcional
Regras importantes:
- O número de SSAs no parâmetro (1) deve bater com a quantidade de SSAs passados nos parâmetros seguintes
- Cada SSA corresponde a um nível da hierarquia, do mais alto para o mais baixo
- Para DLET e REPL, não se passam SSAs — o IMS usa o posicionamento atual
- A função é sempre 4 bytes com espaço no final:
'GU ','GN ','GNP '
3. SSA básico — qualificado e não-qualificado
SSA (Segment Search Argument) é o critério de seleção de segmento — equivale ao WHERE do SQL. Existem dois tipos:
SSA não-qualificado
Identifica apenas o tipo do segmento, sem critério de valor. O IMS retorna o próximo segmento desse tipo na ordem de hierarquia.
01 WS-SSA-CLIENTE-UNQ.
05 FILLER PIC X(08) VALUE 'CLIENTE '.
05 FILLER PIC X(01) VALUE ' '.
^
espaço em branco = não-qualificado
* 9 bytes no total: 8 (nome segmento) + 1 (blank/parêntese)
SSA qualificado
Especifica nome do segmento + nome do campo + operador + valor. O IMS busca o segmento com aquele valor exato no campo.
01 WS-SSA-CLI-QUAL.
05 FILLER PIC X(08) VALUE 'CLIENTE '. -- nome seg (8)
05 FILLER PIC X(01) VALUE '('. -- abre parêntese
05 FILLER PIC X(08) VALUE 'CLICPF '. -- nome field (8)
05 FILLER PIC X(02) VALUE '= '. -- operador (2)
05 SSA-CLI-CPF PIC 9(11). -- valor (n bytes)
05 FILLER PIC X(01) VALUE ')'. -- fecha parêntese
* Operadores válidos:
* '= ' igual
* '< ' menor que
* '<=' menor ou igual
* '> ' maior que
* '>=' maior ou igual
* 'NE' diferente (not equal)
Nome do segmento: exatamente 8 bytes com espaço à direita. Nome do field: exatamente 8 bytes com espaço à direita. Operador: exatamente 2 bytes. Valor: deve ter o mesmo comprimento em bytes que o campo definido no DBD. Um byte a mais ou a menos causa status code AJ (SSA inválido) e pode corromper o posicionamento.
& AND, | OR) e command codes que alteram a navegação (como C para path call ou D para recuperar segmentos descendentes). Esses recursos avançados estão no próximo artigo: SSAs e Qualificação de Chamadas.
4. GU — Get Unique
GU é a busca direta por qualificação — equivale ao SELECT ... WHERE chave = valor. Sempre começa do topo da hierarquia, independente do posicionamento atual. Use quando você sabe exatamente o que quer buscar.
1000-BUSCA-CLIENTE.
MOVE '12345678901' TO SSA-CLI-CPF
CALL 'CBLTDLI' USING
WS-SSA-1
WS-FUNC-GU
PCB-BANCO
WS-SEG-CLIENTE
WS-SSA-CLI-QUAL
EVALUATE PCB-STATUS
WHEN SPACES
DISPLAY 'CLIENTE: ' CLI-NOME
WHEN 'GE'
DISPLAY 'CLIENTE NAO ENCONTRADO'
MOVE 'N' TO WS-CLIENTE-ACHADO
WHEN OTHER
PERFORM 9999-ERRO-IMS
END-EVALUATE.
* GU com 2 SSAs: qualifica cliente E conta
MOVE '12345678901' TO SSA-CLI-CPF
MOVE '001234-5 ' TO SSA-CTA-NUM
CALL 'CBLTDLI' USING
WS-SSA-2
WS-FUNC-GU
PCB-BANCO
WS-SEG-CONTA
WS-SSA-CLI-QUAL
WS-SSA-CTA-QUAL
EVALUATE PCB-STATUS
WHEN SPACES
DISPLAY 'SALDO: ' CTA-SALDO
WHEN 'GE'
DISPLAY 'CONTA NAO ENCONTRADA'
WHEN OTHER
PERFORM 9999-ERRO-IMS
END-EVALUATE.
Ao contrário de GN e GNP, o GU não depende do posicionamento atual — ele sempre varre desde o início do banco. Por isso, GU com SSA qualificado é seguro para usar em qualquer momento do programa, mesmo depois de uma série de GNs.
5. GN — Get Next
GN avança para o próximo segmento em ordem hierárquica pré-ordem (pai antes dos filhos). Usa o posicionamento estabelecido pela call anterior. Sem SSA, varre todos os segmentos do banco em sequência.
2000-VARRE-TODOS-CLIENTES.
* Primeiro GN sem SSA — varre em sequência
PERFORM UNTIL PCB-STATUS = 'GB'
CALL 'CBLTDLI' USING
WS-SSA-1
WS-FUNC-GN
PCB-BANCO
WS-SEG-CLIENTE
WS-SSA-CLI-UNQUAL
EVALUATE PCB-STATUS
WHEN SPACES
PERFORM 2100-PROCESSA-CLIENTE
WHEN 'GB'
CONTINUE
WHEN OTHER
PERFORM 9999-ERRO-IMS
END-EVALUATE
END-PERFORM.
01 WS-SSA-CLI-TIPO.
05 FILLER PIC X(08) VALUE 'CLIENTE '.
05 FILLER PIC X(01) VALUE '('.
05 FILLER PIC X(08) VALUE 'CLITIPO '.
05 FILLER PIC X(02) VALUE '= '.
05 FILLER PIC X(01) VALUE 'J'.
05 FILLER PIC X(01) VALUE ')'.
2500-PROXCLIENTE-JURIDICO.
CALL 'CBLTDLI' USING
WS-SSA-1
WS-FUNC-GN
PCB-BANCO
WS-SEG-CLIENTE
WS-SSA-CLI-TIPO
EVALUATE PCB-STATUS
WHEN SPACES
PERFORM 2600-PROCESSA-JURIDICO
WHEN 'GE'
* Nenhum proximo cliente juridico
MOVE 'S' TO WS-FIM-JURIDICOS
WHEN OTHER
PERFORM 9999-ERRO-IMS
END-EVALUATE.
GN sem SSA retorna qualquer segmento do banco em ordem pré-ordem — clientes, contas, movimentos, endereços, tudo intercalado. Em bancos com hierarquia profunda, use sempre SSA com o nome do segmento desejado para filtrar apenas o tipo que você quer. GN com SSA não-qualificado de CLIENTE retorna apenas clientes e pula todos os dependentes.
6. GNP — Get Next within Parent
GNP é a call mais importante para navegação hierárquica. Ela retorna o próximo segmento filho do pai atual — ou seja, varre os gêmeos de um segmento sem sair do contexto do pai. Quando não há mais filhos, retorna status GE.
3000-VARRE-CONTAS-CLIENTE.
* Primeiro: posicionar no cliente com GU
MOVE '12345678901' TO SSA-CLI-CPF
CALL 'CBLTDLI' USING
WS-SSA-1
WS-FUNC-GU
PCB-BANCO
WS-SEG-CLIENTE
WS-SSA-CLI-QUAL
IF PCB-STATUS NOT = SPACES
DISPLAY 'CLIENTE NAO ENCONTRADO'
GOBACK
END-IF
* Agora varrer os filhos CONTA com GNP
PERFORM UNTIL PCB-STATUS = 'GE'
CALL 'CBLTDLI' USING
WS-SSA-1
WS-FUNC-GNP
PCB-BANCO
WS-SEG-CONTA
WS-SSA-CTA-UNQUAL
EVALUATE PCB-STATUS
WHEN SPACES
DISPLAY 'CONTA: ' CTA-NUM
' SALDO: ' CTA-SALDO
WHEN 'GE'
CONTINUE
WHEN OTHER
PERFORM 9999-ERRO-IMS
END-EVALUATE
END-PERFORM.
Pense em GNP como o equivalente ao READ NEXT de VSAM em modo sequencial, mas limitado aos filhos do pai atual. GU posiciona no pai (como OPEN + START), GNP lê o próximo filho (como READ NEXT), e o status GE indica que acabaram os filhos (como FILE STATUS 10). Esse trio GU + GNP + GE é o padrão de leitura de gêmeos em qualquer programa IMS.
4000-VARRE-MOVIMENTOS.
* GU posiciona no cliente e na conta com 2 SSAs
MOVE '12345678901' TO SSA-CLI-CPF
MOVE '001234-5 ' TO SSA-CTA-NUM
CALL 'CBLTDLI' USING
WS-SSA-2
WS-FUNC-GU
PCB-BANCO
WS-SEG-CONTA
WS-SSA-CLI-QUAL
WS-SSA-CTA-QUAL
IF PCB-STATUS NOT = SPACES
DISPLAY 'CONTA NAO ENCONTRADA'
GOBACK
END-IF
* GNP varre movimentos dessa conta
PERFORM UNTIL PCB-STATUS = 'GE'
CALL 'CBLTDLI' USING
WS-SSA-1
WS-FUNC-GNP
PCB-BANCO
WS-SEG-MOVIMENT
WS-SSA-MOV-UNQUAL
IF PCB-STATUS = SPACES
ADD MOV-VALOR TO WS-TOTAL-MOV
END-IF
END-PERFORM.
7. GHU, GHN, GHNP — Get Hold
Antes de atualizar (REPL) ou deletar (DLET) um segmento, você obrigatoriamente deve tê-lo lido com uma das variantes Get Hold. O "Hold" significa que o IMS mantém um lock no segmento até que você complete a operação ou saia do programa.
| Call Hold | Equivale a | Quando usar |
|---|---|---|
| GHU | GU com lock | Quando você sabe a chave do segmento a atualizar/deletar |
| GHN | GN com lock | Durante varredura sequencial que pode precisar atualizar/deletar |
| GHNP | GNP com lock | Durante varredura de gêmeos que pode precisar atualizar/deletar |
5000-ATUALIZA-STATUS-CONTA.
MOVE '12345678901' TO SSA-CLI-CPF
MOVE '001234-5 ' TO SSA-CTA-NUM
CALL 'CBLTDLI' USING
WS-SSA-2
WS-FUNC-GHU
PCB-BANCO
WS-SEG-CONTA
WS-SSA-CLI-QUAL
WS-SSA-CTA-QUAL
EVALUATE PCB-STATUS
WHEN SPACES
CONTINUE
WHEN 'GE'
DISPLAY 'CONTA NAO ENCONTRADA'
GOBACK
WHEN OTHER
PERFORM 9999-ERRO-IMS
END-EVALUATE
* Modifica os dados na área de trabalho
MOVE 'B' TO CTA-STATUS
* Envia o segmento modificado de volta
CALL 'CBLTDLI' USING
WS-SSA-0
WS-FUNC-REPL
PCB-BANCO
WS-SEG-CONTA
IF PCB-STATUS NOT = SPACES
PERFORM 9999-ERRO-IMS
END-IF.
O IMS mantém o "hold" (lock) no segmento lido com GHU/GHN/GHNP até a próxima REPL ou DLET. Se você fizer qualquer outra call de navegação (GN, GNP) antes do REPL/DLET, o IMS libera o hold e a operação de atualização retorna status DJ (delete) ou RX (replace). A regra é: GHU → modifica dados na WS → REPL/DLET, sem interrupções.
8. REPL — Replace (atualizar)
REPL substitui o conteúdo do segmento em hold pelo conteúdo atual da área de dados do segmento. Você não pode mudar o sequence field (chave) com REPL — para isso, você deleta e reinseriu.
5100-DEBITAR-CONTA.
* Passo 1: ler com hold (GHU)
MOVE '12345678901' TO SSA-CLI-CPF
MOVE '001234-5 ' TO SSA-CTA-NUM
CALL 'CBLTDLI' USING
WS-SSA-2
WS-FUNC-GHU
PCB-BANCO
WS-SEG-CONTA
WS-SSA-CLI-QUAL
WS-SSA-CTA-QUAL
IF PCB-STATUS NOT = SPACES
PERFORM 9999-ERRO-IMS
END-IF
* Passo 2: calcular novo valor
SUBTRACT WS-VALOR-DEBITO FROM CTA-SALDO
* Passo 3: REPL — sem SSAs (usa posicionamento do GHU)
CALL 'CBLTDLI' USING
WS-SSA-0
WS-FUNC-REPL
PCB-BANCO
WS-SEG-CONTA
EVALUATE PCB-STATUS
WHEN SPACES
DISPLAY 'SALDO ATUALIZADO'
WHEN 'RX'
DISPLAY 'HOLD PERDIDO - REPL SEM GHU ANTERIOR'
WHEN OTHER
PERFORM 9999-ERRO-IMS
END-EVALUATE.
REPL e DLET não recebem SSAs — eles operam sobre o segmento em hold. Por convenção, muitos programadores definem
01 WS-SSA-0 PIC S9(05) COMP VALUE 0 e passam como primeiro parâmetro. Alguns sistemas usam VALUE ZERO diretamente. O IMS ignora o valor — o que importa é que não há SSAs após a área de dados.
9. DLET — Delete
DLET deleta o segmento em hold e, por padrão, todos os seus dependentes. Para deletar um segmento que tem filhos, o PSB deve ter PROCOPT=D no segmento e em todos os seus descendentes que serão deletados em cascata.
6000-CANCELA-MOVIMENTO.
* Posicionar no movimento com GHU (3 SSAs: CLI + CTA + MOV)
MOVE '12345678901' TO SSA-CLI-CPF
MOVE '001234-5 ' TO SSA-CTA-NUM
MOVE '20260610' TO SSA-MOV-DATA
CALL 'CBLTDLI' USING
WS-SSA-3
WS-FUNC-GHU
PCB-BANCO
WS-SEG-MOVIMENT
WS-SSA-CLI-QUAL
WS-SSA-CTA-QUAL
WS-SSA-MOV-QUAL
EVALUATE PCB-STATUS
WHEN SPACES
CONTINUE
WHEN 'GE'
DISPLAY 'MOVIMENTO NAO ENCONTRADO'
GOBACK
WHEN OTHER
PERFORM 9999-ERRO-IMS
END-EVALUATE
* DLET — sem SSAs
CALL 'CBLTDLI' USING
WS-SSA-0
WS-FUNC-DLET
PCB-BANCO
WS-SEG-MOVIMENT
IF PCB-STATUS NOT = SPACES
PERFORM 9999-ERRO-IMS
END-IF.
| Status DLET | Significado |
|---|---|
| Espaços | Sucesso — segmento deletado |
| DJ | Segmento tem filhos que não estão no PSB ou PROCOPT não autoriza delete cascata |
| DA | Segment não está em hold — GHU/GHN/GHNP não foi feito antes |
| AM | PROCOPT do PSB não permite DLET neste segmento |
10. ISRT — Insert
ISRT insere um novo segmento no banco. O IMS posiciona o novo segmento de acordo com o sequence field (chave de ordenação) e os SSAs passados para identificar onde na hierarquia inserir.
7000-ABRE-CONTA.
* Preenche a área de dados do novo segmento CONTA
MOVE '999999-0 ' TO CTA-NUM
MOVE 'CC' TO CTA-TIPO
MOVE ZEROS TO CTA-SALDO
MOVE 'A' TO CTA-STATUS
* ISRT com 2 SSAs: identifica o pai (CLIENTE) e o tipo filho
MOVE '12345678901' TO SSA-CLI-CPF
CALL 'CBLTDLI' USING
WS-SSA-2
WS-FUNC-ISRT
PCB-BANCO
WS-SEG-CONTA
WS-SSA-CLI-QUAL (identifica o pai CLIENTE)
WS-SSA-CTA-UNQUAL (tipo do segmento a inserir)
EVALUATE PCB-STATUS
WHEN SPACES
DISPLAY 'CONTA INSERIDA COM SUCESSO'
WHEN 'II'
DISPLAY 'CONTA JA EXISTE (CHAVE DUPLICADA)'
WHEN 'GE'
DISPLAY 'CLIENTE PAI NAO ENCONTRADO'
WHEN OTHER
PERFORM 9999-ERRO-IMS
END-EVALUATE.
7100-INCLUI-CLIENTE.
* Preenche área de dados
MOVE '98765432100' TO CLI-CPF
MOVE 'JOAO SILVA' TO CLI-NOME
MOVE '19800315' TO CLI-NASC
MOVE 'F' TO CLI-TIPO
* ISRT de segmento raiz: 1 SSA não-qualificado
CALL 'CBLTDLI' USING
WS-SSA-1
WS-FUNC-ISRT
PCB-BANCO
WS-SEG-CLIENTE
WS-SSA-CLI-UNQUAL
EVALUATE PCB-STATUS
WHEN SPACES
DISPLAY 'CLIENTE INSERIDO'
WHEN 'II'
DISPLAY 'CPF JA CADASTRADO'
WHEN OTHER
PERFORM 9999-ERRO-IMS
END-EVALUATE.
No ISRT, os SSAs identificam o caminho hierárquico até o pai onde o novo segmento será inserido. O último SSA é sempre não-qualificado e identifica o tipo do segmento que está sendo inserido. Os SSAs anteriores são qualificados e identificam os pais. Isso é diferente do GU, onde o último SSA qualificado identifica o segmento que você quer ler.
11. Status codes completos
| Status | Calls que retornam | Significado e ação |
|---|---|---|
| bb (espaços) | Todas | Sucesso — operação concluída normalmente |
| GE | GU, GN, GNP, ISRT | Segment Not Found — segmento não encontrado. Em GNP: não há mais filhos. Em ISRT: pai não encontrado. |
| GB | GN | End of Database — fim do banco em leitura sequencial. Normal ao final de varredura. |
| GK | GN | Get Next — saiu do contexto do pai atual (usado em combinação com command codes). |
| II | ISRT | Insert: sequence field duplicado. Chave já existe. Verificar se é reprocessamento. |
| DJ | DLET | Delete: segmento tem dependentes que impedem a deleção. Verificar PROCOPT no PSB. |
| DA | DLET, REPL | Segmento não está em hold. Faltou o GHU/GHN/GHNP antes do DLET/REPL. |
| RX | REPL | Replace: hold perdido (outra GN/GNP foi feita entre o GHU e o REPL). |
| AM | Todas | Access Method error — PROCOPT do PSB não autoriza a operação neste segmento. |
| AJ | Todas | SSA inválido — nome de segmento ou field errado, tamanho incorreto. |
| AC | Todas | PCB inválido — ponteiro de PCB incorreto ou PSB não carregado. |
| FD | Todas | Deadlock detectado — dois programas esperando um pelo outro. IMS aborta o programa. |
9999-ERRO-IMS.
DISPLAY '*** ERRO IMS ***'
DISPLAY 'STATUS : [' PCB-STATUS ']'
DISPLAY 'SEGMENTO: [' PCB-SEG-NAME ']'
DISPLAY 'NIVEL : [' PCB-SEG-LEVEL ']'
DISPLAY 'FUNCAO : [' WS-ULTIMA-FUNC ']'
EVALUATE PCB-STATUS
WHEN 'FD'
DISPLAY 'DEADLOCK - PROGRAMA ABORTADO PELO IMS'
WHEN 'AM'
DISPLAY 'SEM AUTORIZACAO - VERIFICAR PSB/PROCOPT'
WHEN 'AJ'
DISPLAY 'SSA INVALIDO - VERIFICAR NOME/TAMANHO'
WHEN OTHER
DISPLAY 'ABEND U0999'
END-EVALUATE
MOVE 12 TO RETURN-CODE
GOBACK.
12. Programa completo — CRUD de conta
Juntando tudo: um programa que recebe um CPF, lê o cliente, varre suas contas, atualiza status e insere um novo movimento.
IDENTIFICATION DIVISION.
PROGRAM-ID. PGMCRUD.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-FUNC-GU PIC X(04) VALUE 'GU '.
01 WS-FUNC-GHU PIC X(04) VALUE 'GHU '.
01 WS-FUNC-GHNP PIC X(04) VALUE 'GHNP'.
01 WS-FUNC-REPL PIC X(04) VALUE 'REPL'.
01 WS-FUNC-ISRT PIC X(04) VALUE 'ISRT'.
01 WS-SSA-0 PIC S9(05) COMP VALUE 0.
01 WS-SSA-1 PIC S9(05) COMP VALUE 1.
01 WS-SSA-2 PIC S9(05) COMP VALUE 2.
01 WS-SSA-3 PIC S9(05) COMP VALUE 3.
01 WS-SEG-CLIENTE.
05 CLI-CPF PIC 9(11).
05 CLI-NOME PIC X(40).
05 CLI-TIPO PIC X(01).
05 FILLER PIC X(28).
01 WS-SEG-CONTA.
05 CTA-NUM PIC X(10).
05 CTA-TIPO PIC X(02).
05 CTA-SALDO PIC S9(13)V99 COMP-3.
05 CTA-STATUS PIC X(01).
05 FILLER PIC X(13).
01 WS-SEG-MOVIMENT.
05 MOV-DATA PIC 9(08).
05 MOV-VALOR PIC S9(11)V99 COMP-3.
05 MOV-TIPO PIC X(01).
05 FILLER PIC X(05).
01 WS-SSA-CLI-QUAL.
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 ')'.
01 WS-SSA-CTA-UNQUAL.
05 FILLER PIC X(09) VALUE 'CONTA '.
01 WS-SSA-MOV-UNQUAL.
05 FILLER PIC X(09) VALUE 'MOVIMENT '.
LINKAGE SECTION.
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-LEN PIC S9(05) COMP.
05 PCB-NUMB-SENS PIC S9(05) COMP.
05 PCB-KEY-FDBK PIC X(21).
PROCEDURE DIVISION.
ENTRY 'DLITCBL' USING PCB-BANCO.
0000-PRINCIPAL.
* 1. Busca cliente
MOVE '12345678901' TO SSA-CLI-CPF
CALL 'CBLTDLI' USING
WS-SSA-1 WS-FUNC-GU PCB-BANCO
WS-SEG-CLIENTE WS-SSA-CLI-QUAL
IF PCB-STATUS NOT = SPACES
DISPLAY 'CLIENTE NAO ENCONTRADO'
GOBACK
END-IF
DISPLAY 'CLIENTE: ' CLI-NOME
* 2. Varre contas e marca ativas como revisadas
PERFORM UNTIL PCB-STATUS = 'GE'
CALL 'CBLTDLI' USING
WS-SSA-1 WS-FUNC-GHNP PCB-BANCO
WS-SEG-CONTA WS-SSA-CTA-UNQUAL
IF PCB-STATUS = SPACES AND CTA-STATUS = 'A'
MOVE 'R' TO CTA-STATUS
CALL 'CBLTDLI' USING
WS-SSA-0 WS-FUNC-REPL PCB-BANCO
WS-SEG-CONTA
DISPLAY 'CONTA REVISADA: ' CTA-NUM
END-IF
END-PERFORM
* 3. Insere movimento de revisao na primeira conta
MOVE '12345678901' TO SSA-CLI-CPF
CALL 'CBLTDLI' USING
WS-SSA-2 WS-FUNC-GU PCB-BANCO
WS-SEG-CONTA WS-SSA-CLI-QUAL WS-SSA-CTA-UNQUAL
IF PCB-STATUS = SPACES
MOVE 20260616 TO MOV-DATA
MOVE ZEROS TO MOV-VALOR
MOVE 'R' TO MOV-TIPO
CALL 'CBLTDLI' USING
WS-SSA-3 WS-FUNC-ISRT PCB-BANCO
WS-SEG-MOVIMENT
WS-SSA-CLI-QUAL
WS-SSA-CTA-UNQUAL
WS-SSA-MOV-UNQUAL
IF PCB-STATUS = SPACES
DISPLAY 'MOVIMENTO INSERIDO'
END-IF
END-IF
GOBACK.
No artigo 03 você vai mergulhar nos SSAs com muito mais profundidade: SSAs booleanos (AND/OR entre campos), command codes que mudam o comportamento de navegação (C para path call, D para delete em path, F para primeiro twin, L para último, N para não-sensível, P para posicionamento), e como passar múltiplos SSAs para navegar hierarquias profundas com precisão.