1. SD — o arquivo de trabalho do SORT
Assim como arquivos comuns usam FD, o arquivo de trabalho do SORT usa SD (Sort Description). Ele declara o layout do registro que será ordenado e é referenciado pelos verbos RELEASE e RETURN:
ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT ARQ-ENTRADA ASSIGN TO DDENTRAD ORGANIZATION IS SEQUENTIAL. SELECT ARQ-SAIDA ASSIGN TO DDSAIDA ORGANIZATION IS SEQUENTIAL. * Arquivo de trabalho: ASSIGN TO deve bater com DD no JCL * ou usar SORTWK01 (DD gerada automaticamente pelo sistema) SELECT ARQ-SORT ASSIGN TO SORTWK01. DATA DIVISION. FILE SECTION. FD ARQ-ENTRADA. 01 REG-ENTRADA. 05 EN-CPF PIC X(11). 05 EN-DATA PIC 9(08). 05 EN-VALOR PIC S9(13)V99. 05 EN-TIPO PIC X(01). 05 EN-FILLER PIC X(25). * SD no lugar de FD para o arquivo de ordenação SD ARQ-SORT. 01 REG-SORT. 05 SK-CPF PIC X(11). *chave de ordenação 05 SK-DATA PIC 9(08). *chave de ordenação 05 SK-VALOR PIC S9(13)V99. 05 SK-TIPO PIC X(01). 05 SK-FILLER PIC X(25).
💗 Para iniciantes — SD vs FD
FDdeclara um arquivo real (de entrada ou saída) que você abre e fecha explicitamente comOPEN/CLOSESDdeclara o arquivo de trabalho temporário que o SORT usa internamente — você nunca abre ou fecha com OPEN/CLOSE; o verboSORTgerencia isso- O layout do
SDnão precisa ser idêntico ao doFD, mas o tamanho do registro deve ser o mesmo
2. SORT com USING e GIVING
A forma mais simples: lê o arquivo de entrada (USING), ordena pelas chaves especificadas e grava no arquivo de saída (GIVING). Não há lógica de filtragem ou processamento intermediário:
PROCEDURE DIVISION. 0000-INICIO. * Ordena ARQ-ENTRADA por CPF crescente e data crescente * e grava resultado em ARQ-SAIDA SORT ARQ-SORT ON ASCENDING KEY SK-CPF ON ASCENDING KEY SK-DATA USING ARQ-ENTRADA GIVING ARQ-SAIDA STOP RUN. * Ordem descendente em uma das chaves SORT ARQ-SORT ON ASCENDING KEY SK-CPF ON DESCENDING KEY SK-DATA *data mais recente primeiro USING ARQ-ENTRADA GIVING ARQ-SAIDA * Múltiplos arquivos de entrada (mesma estrutura) SORT ARQ-SORT ON ASCENDING KEY SK-CPF USING ARQ-JANEIRO ARQ-FEVEREIRO ARQ-MARCO GIVING ARQ-SAIDA
✅ USING/GIVING abre e fecha os arquivos automaticamente
Com USING e GIVING, o COBOL abre os arquivos antes de ordenar e os fecha ao terminar. Não chame OPEN nem CLOSE para esses arquivos antes ou depois do SORT — você receberá um erro de arquivo já aberto. Se precisar processar os dados antes ou depois da ordenação, use INPUT PROCEDURE e OUTPUT PROCEDURE.
3. SORT com INPUT PROCEDURE
Quando você precisa filtrar ou transformar os registros antes de ordená-los, substitua o USING por INPUT PROCEDURE. Sua procedure lê o arquivo de entrada, processa cada registro e usa RELEASE para enviá-lo ao sort:
PROCEDURE DIVISION. 0000-INICIO. OPEN INPUT ARQ-ENTRADA SORT ARQ-SORT ON ASCENDING KEY SK-CPF SK-DATA INPUT PROCEDURE IS 1000-FILTRA-ENTRADA GIVING ARQ-SAIDA CLOSE ARQ-ENTRADA STOP RUN. * INPUT PROCEDURE: lê a entrada e passa apenas o que interessa 1000-FILTRA-ENTRADA. MOVE 'N' TO WS-FIM READ ARQ-ENTRADA AT END SET FIM-ARQUIVO TO TRUE END-READ PERFORM UNTIL FIM-ARQUIVO * Filtra: envia ao sort apenas tipo 'C' (crédito) IF EN-TIPO = 'C' MOVE EN-CPF TO SK-CPF MOVE EN-DATA TO SK-DATA MOVE EN-VALOR TO SK-VALOR MOVE EN-TIPO TO SK-TIPO RELEASE REG-SORT *envia para o sort END-IF READ ARQ-ENTRADA AT END SET FIM-ARQUIVO TO TRUE END-READ END-PERFORM. * RELEASE FROM: preenche o REG-SORT e envia em um passo * (quando o layout de entrada e o SD são idênticos) RELEASE REG-SORT FROM REG-ENTRADA
🦕 Analogia — RELEASE é como colocar na fila
Imagine o SORT como um funcionário que organiza fichas em ordem. A INPUT PROCEDURE é você selecionando quais fichas entregar. O RELEASE é o ato de entregar cada ficha para ele. Depois que você termina de entregar (a procedure retorna), ele ordena tudo e grava no arquivo de saída.
4. SORT com OUTPUT PROCEDURE
Quando você precisa processar ou transformar os registros já ordenados antes de gravar, substitua o GIVING por OUTPUT PROCEDURE. Sua procedure usa RETURN para buscar cada registro do sort já em ordem:
PROCEDURE DIVISION. 0000-INICIO. OPEN OUTPUT ARQ-SAIDA SORT ARQ-SORT ON ASCENDING KEY SK-CPF USING ARQ-ENTRADA OUTPUT PROCEDURE IS 2000-PROCESSA-ORDENADO CLOSE ARQ-SAIDA STOP RUN. * OUTPUT PROCEDURE: consome o sort já ordenado 2000-PROCESSA-ORDENADO. MOVE 'N' TO WS-FIM MOVE SPACES TO WS-CPF-ANTERIOR MOVE ZEROS TO WS-TOTAL-CPF RETURN ARQ-SORT *busca primeiro registro ordenado AT END SET FIM-ARQUIVO TO TRUE END-RETURN PERFORM UNTIL FIM-ARQUIVO * Detecta quebra de grupo (change of CPF) IF SK-CPF = WS-CPF-ANTERIOR ADD SK-VALOR TO WS-TOTAL-CPF ELSE IF WS-CPF-ANTERIOR NOT = SPACES PERFORM 2100-GRAVA-TOTAL END-IF MOVE SK-CPF TO WS-CPF-ANTERIOR MOVE SK-VALOR TO WS-TOTAL-CPF END-IF RETURN ARQ-SORT AT END SET FIM-ARQUIVO TO TRUE END-RETURN END-PERFORM IF WS-CPF-ANTERIOR NOT = SPACES PERFORM 2100-GRAVA-TOTAL END-IF. 2100-GRAVA-TOTAL. MOVE WS-CPF-ANTERIOR TO SA-CPF MOVE WS-TOTAL-CPF TO SA-TOTAL WRITE REG-SAIDA FROM WS-LINHA-SAIDA.
5. SORT com INPUT e OUTPUT PROCEDURE
Você pode combinar as duas procedures no mesmo SORT — filtra na entrada, ordena, processa na saída:
PROCEDURE DIVISION. 0000-INICIO. OPEN INPUT ARQ-ENTRADA OUTPUT ARQ-SAIDA SORT ARQ-SORT ON ASCENDING KEY SK-CPF SK-DATA INPUT PROCEDURE IS 1000-FILTRA-ENTRADA OUTPUT PROCEDURE IS 2000-PROCESSA-SAIDA CLOSE ARQ-ENTRADA ARQ-SAIDA STOP RUN.
| Forma | Entrada | Saída | Quando usar |
|---|---|---|---|
USING / GIVING | Automática | Automática | Ordenação simples sem processamento |
INPUT PROC / GIVING | Manual (RELEASE) | Automática | Filtrar/transformar antes de ordenar |
USING / OUTPUT PROC | Automática | Manual (RETURN) | Processar/acumular após ordenar |
INPUT PROC / OUTPUT PROC | Manual (RELEASE) | Manual (RETURN) | Filtro na entrada e processamento na saída |
6. MERGE — mesclando arquivos ordenados
O MERGE combina dois ou mais arquivos que já estão ordenados pelas mesmas chaves, produzindo um único arquivo ordenado. É mais eficiente do que reunir os arquivos e ordenar novamente:
ENVIRONMENT DIVISION. FILE-CONTROL. SELECT ARQ-JAN ASSIGN TO DDJAN ORGANIZATION IS SEQUENTIAL. SELECT ARQ-FEV ASSIGN TO DDFEV ORGANIZATION IS SEQUENTIAL. SELECT ARQ-MAR ASSIGN TO DDMAR ORGANIZATION IS SEQUENTIAL. SELECT ARQ-TRIM ASSIGN TO DDTRIM ORGANIZATION IS SEQUENTIAL. SELECT ARQ-MERGE ASSIGN TO SORTMRG1. DATA DIVISION. FILE SECTION. * FDs para os três arquivos de entrada e o de saída... SD ARQ-MERGE. 01 REG-MERGE. 05 MG-CPF PIC X(11). 05 MG-DATA PIC 9(08). 05 MG-RESTO PIC X(39). PROCEDURE DIVISION. 0000-INICIO. * Os três arquivos devem estar ordenados por CPF e DATA MERGE ARQ-MERGE ON ASCENDING KEY MG-CPF MG-DATA USING ARQ-JAN ARQ-FEV ARQ-MAR GIVING ARQ-TRIM STOP RUN. * MERGE também aceita OUTPUT PROCEDURE MERGE ARQ-MERGE ON ASCENDING KEY MG-CPF USING ARQ-JAN ARQ-FEV ARQ-MAR OUTPUT PROCEDURE IS 2000-PROCESSA-MERGE
⚠️ MERGE não tem INPUT PROCEDURE
Diferente do SORT, o MERGE não aceita INPUT PROCEDURE. Os arquivos de entrada devem estar todos corretamente ordenados pelas mesmas chaves antes de serem passados ao MERGE. Se precisar filtrar ou transformar a entrada, use um SORT com INPUT PROCEDURE antes de chamar o MERGE, ou use o SORT com múltiplos arquivos no USING.
7. SORT COBOL vs DFSORT no JCL
Em produção, a maioria das ordenações simples é feita pelo utilitário DFSORT (ou SYNCSORT) diretamente no JCL, sem passar por um programa COBOL. Quando usar cada abordagem:
//SORTSTEP EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=PROD.MOVIMENTO.DIARIO,DISP=SHR
//SORTOUT DD DSN=PROD.MOVIMENTO.ORDENADO,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(5,2)),RECFM=FB,LRECL=60
//SYSIN DD *
SORT FIELDS=(1,11,CH,A, <- CPF posição 1 tamanho 11, alfanum, ascend
12,8,CH,A) <- DATA posição 12 tamanho 8, alfanum, ascend
INCLUDE COND=(20,1,CH,EQ,C'C') <- filtra só tipo 'C'
/*
| SORT no COBOL | DFSORT no JCL | |
|---|---|---|
| Lógica complexa | ✅ Permite código COBOL completo | ❌ Limitado às opções do utilitário |
| Filtros simples | Possível com INPUT PROC | ✅ INCLUDE/OMIT muito mais simples |
| Performance | Boa | ✅ Melhor — otimizado para hardware |
| Manutenção | Requer recompilação | ✅ Altera só o JCL |
| Transformação de dados | ✅ Total via OUTPUT PROCEDURE | Limitada a operações básicas |
| Quando usar | Quando há lógica de negócio integrada | Para ordenações e filtros simples |
🟣 Para quem já programa — SORT COBOL chama DFSORT internamente
No IBM z/OS, quando você executa o verbo SORT do COBOL, ele chama o DFSORT (ou SYNCSORT, dependendo do instalado) por baixo dos panos. O pré-processador de sort transforma as DDs do JCL automaticamente. Por isso o performance é comparável — você não perde nada usando o verbo COBOL. A diferença real está na flexibilidade: com INPUT/OUTPUT PROCEDURE você tem o poder total do COBOL para filtrar e processar.
8. Exemplo completo
Um programa que lê um arquivo de movimentos, filtra apenas os débitos acima de R$1.000, ordena por CPF e data, e gera um relatório com total por cliente:
IDENTIFICATION DIVISION. PROGRAM-ID. RELDEBITO. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT ARQ-MOVIMENTO ASSIGN TO DDMOVTO ORGANIZATION IS SEQUENTIAL FILE STATUS IS WS-FS-MOV. SELECT ARQ-RELATORIO ASSIGN TO DDRELAT ORGANIZATION IS SEQUENTIAL FILE STATUS IS WS-FS-REL. SELECT ARQ-WORKSORT ASSIGN TO SORTWK01. DATA DIVISION. FILE SECTION. FD ARQ-MOVIMENTO. 01 REG-MOVIMENTO. 05 MV-CPF PIC X(11). 05 MV-DATA PIC 9(08). 05 MV-TIPO PIC X(01). 88 MV-DEBITO VALUE 'D'. 05 MV-VALOR PIC S9(11)V99. 05 MV-FILLER PIC X(26). FD ARQ-RELATORIO. 01 REG-RELATORIO PIC X(80). SD ARQ-WORKSORT. 01 REG-WORKSORT. 05 WK-CPF PIC X(11). 05 WK-DATA PIC 9(08). 05 WK-TIPO PIC X(01). 05 WK-VALOR PIC S9(11)V99. 05 WK-FILLER PIC X(26). WORKING-STORAGE SECTION. 01 WS-FS-MOV PIC X(02). 01 WS-FS-REL PIC X(02). 01 WS-FIM-ENT PIC X(01). 88 FIM-ENTRADA VALUE 'S'. 01 WS-FIM-SORT PIC X(01). 88 FIM-SORT VALUE 'S'. 01 WS-CPF-ANT PIC X(11). 01 WS-TOTAL-CLI PIC S9(11)V99. 01 WS-LIMITE PIC S9(11)V99 VALUE 1000.00. 01 WS-LINHA PIC X(80). PROCEDURE DIVISION. 0000-INICIO. OPEN INPUT ARQ-MOVIMENTO OUTPUT ARQ-RELATORIO SORT ARQ-WORKSORT ON ASCENDING KEY WK-CPF ON ASCENDING KEY WK-DATA INPUT PROCEDURE IS 1000-SELECIONA OUTPUT PROCEDURE IS 2000-RELATORIO CLOSE ARQ-MOVIMENTO ARQ-RELATORIO STOP RUN. 1000-SELECIONA. MOVE 'N' TO WS-FIM-ENT READ ARQ-MOVIMENTO AT END SET FIM-ENTRADA TO TRUE END-READ PERFORM UNTIL FIM-ENTRADA IF MV-DEBITO AND MV-VALOR >= WS-LIMITE RELEASE REG-WORKSORT FROM REG-MOVIMENTO END-IF READ ARQ-MOVIMENTO AT END SET FIM-ENTRADA TO TRUE END-READ END-PERFORM. 2000-RELATORIO. MOVE 'N' TO WS-FIM-SORT MOVE SPACES TO WS-CPF-ANT MOVE ZEROS TO WS-TOTAL-CLI RETURN ARQ-WORKSORT AT END SET FIM-SORT TO TRUE END-RETURN PERFORM UNTIL FIM-SORT IF WK-CPF NOT = WS-CPF-ANT IF WS-CPF-ANT NOT = SPACES PERFORM 2100-IMPRIME-TOTAL END-IF MOVE WK-CPF TO WS-CPF-ANT MOVE ZEROS TO WS-TOTAL-CLI END-IF ADD WK-VALOR TO WS-TOTAL-CLI RETURN ARQ-WORKSORT AT END SET FIM-SORT TO TRUE END-RETURN END-PERFORM IF WS-CPF-ANT NOT = SPACES PERFORM 2100-IMPRIME-TOTAL END-IF. 2100-IMPRIME-TOTAL. STRING WS-CPF-ANT DELIMITED SIZE ' TOTAL: ' DELIMITED SIZE WS-TOTAL-CLI DELIMITED SIZE INTO WS-LINHA END-STRING WRITE REG-RELATORIO FROM WS-LINHA.
9. Erros comuns
1. OPEN/CLOSE nos arquivos de USING/GIVING
* ERRADO: SORT com USING/GIVING gerencia OPEN e CLOSE OPEN INPUT ARQ-ENTRADA *erro: já vai ser aberto pelo SORT SORT ARQ-SORT ON ASCENDING KEY SK-CPF USING ARQ-ENTRADA GIVING ARQ-SAIDA * CORRETO: não abra/feche quando usar USING/GIVING SORT ARQ-SORT ON ASCENDING KEY SK-CPF USING ARQ-ENTRADA GIVING ARQ-SAIDA * Com INPUT/OUTPUT PROCEDURE: você abre e fecha manualmente OPEN INPUT ARQ-ENTRADA OUTPUT ARQ-SAIDA SORT ARQ-SORT ... INPUT PROCEDURE IS 1000-ENTRADA OUTPUT PROCEDURE IS 2000-SAIDA CLOSE ARQ-ENTRADA ARQ-SAIDA
2. GO TO de dentro da INPUT/OUTPUT PROCEDURE
* ERRADO: transferir controle para fora da INPUT/OUTPUT PROCEDURE * com GO TO causa comportamento indefinido 1000-FILTRA-ENTRADA. READ ARQ-ENTRADA AT END GO TO 9000-TRATA-ERRO *PERIGOSO: fora da procedure END-READ. * CORRETO: trate erros dentro da própria procedure 1000-FILTRA-ENTRADA. READ ARQ-ENTRADA AT END SET FIM-ENTRADA TO TRUE END-READ IF WS-FS-MOV NOT = '00' AND WS-FS-MOV NOT = '10' MOVE 'S' TO WS-ERRO-SORT SET FIM-ENTRADA TO TRUE *aborta a procedure END-IF.
3. Chave de SORT com tipo numérico em campo alfanumérico
* Ordenar valor numérico declarado como X ordena por string * '10' vem antes de '9' em ordenação alfanumérica (compare '1' vs '9') SD ARQ-SORT. 01 REG-SORT. 05 SK-VALOR PIC X(13). *ERRADO para ordenar numericamente * CORRETO: declare a chave com o tipo real 01 REG-SORT. 05 SK-VALOR PIC S9(11)V99. *correto: numérico ordenado por valor
🟣 Para quem já programa — SORT ON EXCEPTION e RETURN-CODE
O verbo SORT não tem cláusula ON EXCEPTION como o CALL. Para detectar falha na ordenação, verifique o RETURN-CODE logo após o SORT: código 0 é sucesso, 16 indica erro grave no sort (espaço insuficiente, arquivo inacessível etc.). Também defina SORT-RETURN em Working Storage como PIC S9(4) COMP — ao usar SORT no COBOL, o runtime preenche esse campo especial automaticamente.