☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

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

sábado, 9 de dezembro de 2023

SQL sem Mistérios no Db2 for z/OS

 

Bellacosa Mainframe e o sql sem misterios no db2 for z/os

☕ Um Café no Bellacosa Mainframe

SQL sem Mistérios no Db2 for z/OS

A Jornada Completa de uma Query no IBM Z — O Guia Definitivo do Programador COBOL Padawan Inspirado em Jornada nas Estrelas

"A lógica é o começo da sabedoria, não o fim."

— Sr. Spock


Introdução — Bem-vindo à USS Enterprise... digo... ao IBM Z

Imagine que você acabou de embarcar na USS Enterprise.

Você é um jovem cadete da Academia da Frota Estelar.

Seu trabalho não é pilotar a nave.

Também não é disparar phasers.

Sua missão é muito mais importante.

Você precisa descobrir como um simples pedido chega ao computador da nave, é analisado, processado e retorna em poucos milissegundos.

No universo Star Trek, esse computador responde perguntas como:

"Computador, localizar todos os oficiais Vulcanos da nave."

No mundo corporativo existe outro computador igualmente impressionante.

Ele atende pelo nome de IBM Z.

E seu cérebro de dados chama-se Db2 for z/OS.

Quando um programa COBOL executa um simples:

SELECT *
FROM CLIENTE
WHERE CPF='12345678900'

A maioria dos iniciantes imagina algo parecido com isto:

"O Db2 abriu a tabela, procurou o CPF e devolveu o registro."

Se fosse tão simples, este artigo terminaria aqui.

Mas...

Na realidade, entre o momento em que o programa envia o SQL e o momento em que os dados retornam, acontece uma verdadeira operação digna da Frota Estelar.

São dezenas de decisões inteligentes.

Milhares de estatísticas.

Análises matemáticas.

Escolha de estratégias.

Gerenciamento de memória.

Uso de caches.

Escolha de índices.

Controle de concorrência.

Tudo isso acontece quase instantaneamente.

Hoje vamos fazer uma viagem completa por essa jornada.

Prepare seu café.

Dr. Spock será nosso guia.


Capítulo 1 — O Computador Nunca Faz Apenas o Que Você Escreveu

Existe um dos maiores mitos entre iniciantes.

"Eu escrevi primeiro o SELECT."

Então ele executa primeiro.

Errado.

Na verdade, o Db2 praticamente ignora a ordem em que você escreveu.

Ele interpreta a intenção da consulta.

Depois decide sozinho como obter o resultado da forma mais eficiente possível.

É exatamente como Spock faria.

Se Kirk diz:

"Chegue até Vulcano."

Spock não pergunta:

"Qual estrada devo pegar?"

Ele calcula:

  • combustível

  • gravidade

  • buracos negros

  • campos de dobra

  • rotas inimigas

  • economia de energia

O destino é o mesmo.

O caminho muda.

O Db2 pensa exatamente assim.


Capítulo 2 — A Ponte de Comando do Db2

Imagine a ponte da Enterprise.

Cada oficial possui uma função.

No Db2 também.

OficialComponente Db2
Capitão KirkAplicação COBOL
Sr. SpockOptimizer
ScottyBuffer Manager
UhuraSQL Parser
SuluAccess Path
ChekovIndex Manager
ComputadorBuffer Pools
EngenhariaDisk Storage

O COBOL faz a pergunta.

Spock decide a melhor estratégia.

Scotty garante que tudo funcione.

O computador responde.


Capítulo 3 — A Missão Começa: EXEC SQL

Tudo começa aqui.

EXEC SQL

SELECT NOME

INTO :WS-NOME

FROM CLIENTES

WHERE CPF=:WS-CPF

END-EXEC.

Parece simples.

Mas isso ainda nem é SQL.

O COBOL sequer entende SQL.

Quem entende é o Pré-compilador.


Capítulo 4 — O Tradutor Universal

Antes da compilação acontece algo exclusivo do mundo Mainframe.

O famoso:

Pré-Compiler.

Ele encontra cada bloco EXEC SQL.

Substitui por chamadas internas.

Gera o famoso:

DBRM

(Database Request Module)

Este DBRM será utilizado posteriormente no BIND.

Curiosidade:

Oracle não trabalha assim.

SQL Server também não.

Este é um dos diferenciais históricos do Db2 z/OS.


Capítulo 5 — O Conselho Vulcano: BIND

Aqui mora uma das maiores diferenças entre o Db2 e praticamente todos os bancos relacionais.

O comando:

BIND PACKAGE

é como uma reunião do Alto Conselho Vulcano.

O Db2 olha para a consulta e pensa:

"Se esta SQL for executada milhões de vezes, qual será o melhor caminho?"

Ele cria um PACKAGE, contendo o plano de acesso ideal para aquele momento.

É aqui que nasce o famoso Access Path.


Capítulo 6 — O Dr. Spock Analisa as Probabilidades

Imagine duas tabelas.

CLIENTES

50 milhões de linhas.

ESTADOS

27 linhas.

Você faria o JOIN começando por qual?

Até um cadete responderia:

ESTADOS.

Mas...

Como o Db2 sabe disso?

A resposta chama-se:

RUNSTATS.


Capítulo 7 — RUNSTATS: Os Sensores de Longo Alcance

Os sensores da Enterprise informam:

  • quantas naves existem;

  • velocidade;

  • distância;

  • massa.

O RUNSTATS faz exatamente isso.

Ele informa ao Optimizer:

  • quantidade de linhas;

  • cardinalidade;

  • distribuição;

  • frequência;

  • seletividade;

  • clustering;

  • número de páginas;

  • estatísticas dos índices.

Sem RUNSTATS...

O Optimizer fica praticamente cego.

E um Spock sem sensores toma decisões muito piores.


Capítulo 8 — Álgebra Relacional: O Idioma Secreto do Computador

Depois que o SQL é validado, ele deixa de existir como texto.

Internamente transforma-se em Álgebra Relacional.

Por exemplo:

SELECT NOME
FROM CLIENTES
WHERE CIDADE='SP'

vira algo semelhante a:

σ Cidade='SP'

↓

π Nome

↓

CLIENTES

Ou seja:

primeiro seleciona.

Depois projeta.

O SQL desaparece.

Nasce um plano matemático.


Capítulo 9 — O Optimizer: O Verdadeiro Sr. Spock do IBM Z

Se existe um personagem que representa perfeitamente o Optimizer...

é o próprio Spock.

Ele nunca trabalha por emoção.

Somente lógica.

Ele calcula:

  • custo de CPU;

  • custo de I/O;

  • uso de Buffer Pools;

  • seletividade dos índices;

  • paralelismo;

  • volume esperado;

  • quantidade de páginas;

  • custo de SORT;

  • bloqueios.

Depois escolhe o menor custo possível.

Nem sempre será o caminho mais curto.

Será o mais eficiente.


Capítulo 10 — A Ordem Lógica da Consulta

Agora chegamos ao famoso diagrama.

Embora escrevamos:

SELECT

FROM

JOIN

ON

WHERE

GROUP BY

HAVING

ORDER BY

FETCH FIRST

O Db2 raciocina assim:

FROM

↓

JOIN

↓

ON

↓

WHERE

↓

GROUP BY

↓

HAVING

↓

SELECT

↓

ORDER BY

↓

FETCH FIRST

Mas cuidado.

Isto ainda não representa a ordem física.

Ela continua sendo decidida pelo Optimizer.


Capítulo 11 — O Access Path: A Rota Estelar

Aqui está o segredo.

O Db2 pode resolver exatamente a mesma SQL de dezenas de maneiras diferentes.

Ele escolhe entre:

  • Table Space Scan;

  • Index Scan;

  • Index Only Access;

  • List Prefetch;

  • Dynamic Prefetch;

  • Sequential Detection;

  • Nested Loop Join;

  • Merge Scan Join;

  • Hybrid Join;

  • Star Join;

  • Parallelism;

  • Materialized Query Table;

  • Sparse Index.

É como escolher diferentes rotas pelo Quadrante Alfa.

O destino é igual.

O caminho muda.


Capítulo 12 — O Buffer Pool: O Scotty da Memória

Scotty sempre dizia:

"Captain, I'm giving her all she's got!"

O Buffer Pool faz exatamente isso.

Antes de acessar o disco...

Ele pergunta:

"Essa página já está na memória?"

Se estiver...

Não existe I/O.

A resposta vem em microssegundos.

Grande parte do desempenho do Db2 depende da eficiência dos Buffer Pools.


Capítulo 13 — Os Predicados Stage 1 e Stage 2

Aqui existe uma armadilha clássica.

Observe:

WHERE YEAR(DATA)=2026

Parece bonito.

Mas destrói o uso do índice.

Muito melhor:

WHERE DATA BETWEEN
'2026-01-01'
AND
'2026-12-31'

No primeiro caso:

Stage 2.

No segundo:

Stage 1.

O primeiro costuma obrigar o Db2 a avaliar linha por linha.

O segundo permite filtrar diretamente pelo índice.

Dica Bellacosa: sempre que possível, escreva predicados que possam ser avaliados durante o acesso aos dados. Essa é uma das otimizações mais valiosas para quem desenvolve em COBOL com Db2.


Capítulo 14 — EXPLAIN: A Caixa-Preta da Enterprise

Nenhum engenheiro sério tenta descobrir um problema apenas olhando para a nave.

Ele consulta os sensores.

No Db2 fazemos exatamente isso.

Utilizamos:

EXPLAIN

Ele revela:

  • qual índice foi escolhido;

  • ordem dos JOINs;

  • tipo de acesso;

  • custo estimado;

  • necessidade de SORT;

  • paralelismo;

  • número estimado de linhas.

Nunca adivinhe.

Sempre consulte o plano.


Capítulo 15 — Locks: O Controle de Segurança da Federação

Enquanto tudo acontece...

O Db2 protege os dados.

Existem diversos tipos de bloqueio:

  • IS (Intent Share)

  • IX (Intent Exclusive)

  • S (Share)

  • U (Update)

  • X (Exclusive)

  • SIX (Share with Intent Exclusive)

Além disso, os níveis de isolamento (UR, CS, RS e RR) determinam o equilíbrio entre concorrência e consistência. Em sistemas bancários e de cartões de crédito, essa gestão é essencial para evitar leituras incorretas, perdas de atualização e conflitos entre milhares de transações simultâneas.


Capítulo 16 — Paralelismo: Quando a Enterprise Usa Toda a Tripulação

Em grandes consultas analíticas, o Db2 pode dividir o trabalho.

Imagine:

CPU 1 lê uma partição.

CPU 2 lê outra.

CPU 3 realiza o JOIN.

CPU 4 faz a agregação.

No IBM Z isso acontece utilizando múltiplos processadores e, em muitos cenários, explorando zIIPs para determinadas cargas elegíveis, reduzindo o impacto sobre os CPs tradicionais.


Capítulo 17 — Quando Fazer REBIND?

Imagine que a Enterprise recebeu um novo motor de dobra.

Você continuaria usando os cálculos antigos?

Claro que não.

No Db2 acontece o mesmo.

Após mudanças significativas, como:

  • criação de índices;

  • remoção de índices;

  • crescimento expressivo das tabelas;

  • execução de RUNSTATS;

  • alterações na distribuição dos dados;

vale analisar um REBIND PACKAGE ou REBIND PLAN, permitindo que o Optimizer recalcule um novo Access Path mais eficiente.


Capítulo 18 — O Programador COBOL Jedi... ou Vulcano?

Existe um momento em que o programador deixa de escrever SQL "que funciona".

E começa a escrever SQL "que escala".

Ele passa a pensar:

  • Meu predicado usa índice?

  • Meu JOIN é seletivo?

  • O EXPLAIN confirma minha hipótese?

  • As estatísticas estão atualizadas?

  • O SORT pode ser eliminado?

  • Estou lendo mais linhas do que preciso?

  • O FETCH FIRST pode reduzir trabalho?

  • Existe uma forma mais eficiente de escrever esta consulta?

Esse é o verdadeiro salto de maturidade.


Easter Egg Bellacosa ☕

No episódio "The Ultimate Computer", a Enterprise recebe o computador M-5, projetado para tomar decisões automaticamente.

No começo, tudo parece perfeito.

Depois surgem consequências inesperadas.

O Db2 Optimizer lembra um pouco essa história.

Ele toma decisões sozinho, mas depende da qualidade das informações que recebe.

Se as estatísticas estiverem desatualizadas, um índice importante não existir ou o modelo físico estiver inadequado, até um excelente otimizador poderá escolher um plano ruim.

A diferença é que, felizmente, o Optimizer não tenta assumir o comando da Enterprise nem entra em combate por conta própria.


Curiosidades

  • O Db2 for z/OS está entre os bancos de dados com os otimizadores mais sofisticados do mercado, evoluindo continuamente desde a década de 1980.

  • Um único SELECT pode gerar dezenas de operações internas invisíveis ao desenvolvedor.

  • Em ambientes de missão crítica, o mesmo SQL pode ser executado milhões de vezes por dia, tornando pequenas otimizações responsáveis por economias enormes de CPU e tempo.

  • Muitos problemas de desempenho atribuídos ao COBOL, na verdade, são consequência de SQL mal escrito ou de um plano de acesso inadequado.


Conclusão — A Lógica é a Maior Aliada do Programador

Ao final desta jornada, descobrimos que uma instrução SQL percorre um caminho muito maior do que imaginávamos. Ela nasce no programa COBOL, passa pelo pré-compilador, gera um DBRM, é ligada a PACKAGEs e PLANs durante o BIND, tem seu plano analisado pelo Optimizer, consulta estatísticas produzidas pelo RUNSTATS, escolhe um Access Path, utiliza Buffer Pools, controla bloqueios, decide estratégias de JOIN e somente então retorna os dados solicitados.

Para um programador COBOL Padawan, compreender essa sequência é um divisor de águas. Você deixa de enxergar o Db2 como uma simples "caixa-preta" e passa a entendê-lo como um verdadeiro computador da Frota Estelar: um sistema que utiliza lógica, estatística e otimização para tomar a melhor decisão possível a cada consulta.

Como diria o Sr. Spock, "A lógica é o começo da sabedoria, não o fim." No universo do IBM Z, essa lógica está presente em cada SELECT, em cada índice e em cada plano de acesso. Quanto melhor você compreender esse funcionamento, mais preparado estará para construir aplicações COBOL rápidas, escaláveis e confiáveis — dignas de uma missão de cinco anos explorando as fronteiras da computação corporativa.

sábado, 1 de julho de 2023

☕ SQL NO MAINFRAME: MUITO ALÉM DO SELECT

 

Bellacosa Mainframe e o SQL no Mainframe muito alem do select



☕ SQL NO MAINFRAME: MUITO ALÉM DO SELECT

Como Dominar os Fundamentos de SQL no DB2 13 for z/OS

Quando alguém abre o SPUFI, Data Studio, DBeaver ou qualquer ferramenta SQL pela primeira vez, normalmente executa algo simples:

SELECT *
FROM CLIENTES;

A consulta retorna dados.

O usuário sorri.

Acredita que aprendeu SQL.

Mas na realidade acabou de dar apenas o primeiro passo de uma longa jornada.

No universo Mainframe, SQL é a língua falada entre:

  • COBOL

  • CICS

  • IMS

  • Java

  • Web Services

  • APIs REST

  • z/OS Connect

  • Analytics

  • Inteligência Artificial

Todo sistema corporativo moderno passa por SQL em algum momento.

E o DB2 13 elevou ainda mais essa importância.


A HISTÓRIA QUE TODO PROFISSIONAL DE MAINFRAME DEVERIA CONHECER

Antes do SQL, bancos relacionais eram apenas uma teoria.

Em 1970, Edgar F. Codd publicou um artigo revolucionário na IBM:

A Relational Model of Data for Large Shared Data Banks

Esse trabalho mudou a computação.

A ideia era simples:

Ao invés de navegar registros fisicamente, os usuários deveriam dizer:

"Quero estes dados."

E o banco decidiria:

"Eu descubro a melhor forma de encontrá-los."

Nascia o conceito de SQL.

Décadas depois, essa filosofia continua viva dentro do DB2 13.


O QUE É SQL?

SQL significa:

Structured Query Language

Ou:

Linguagem Estruturada de Consulta

Ela permite:

  • Consultar dados

  • Inserir dados

  • Alterar dados

  • Excluir dados

  • Criar estruturas

  • Gerenciar segurança

Praticamente tudo que fazemos no DB2 passa por SQL.


OS QUATRO GRANDES GRUPOS DE COMANDOS SQL

DQL – Data Query Language

Consulta de dados.

Exemplo:

SELECT *
FROM FUNCIONARIOS;

DML – Data Manipulation Language

Manipulação de registros.

INSERT INTO FUNCIONARIOS
VALUES
(100,'CARLOS');
UPDATE FUNCIONARIOS
SET SALARIO = 5000
WHERE MATRICULA = 100;
DELETE
FROM FUNCIONARIOS
WHERE MATRICULA = 100;

DDL – Data Definition Language

Definição das estruturas.

CREATE TABLE CLIENTES
(
 ID INTEGER,
 NOME VARCHAR(50)
);

DCL – Data Control Language

Controle de segurança.

GRANT SELECT
ON CLIENTES
TO USER01;

A TABELA É O CORAÇÃO DO DB2

Imagine um arquivo VSAM KSDS.

Agora imagine esse conceito evoluído.

Uma tabela é composta por:

  • Linhas

  • Colunas

  • Relacionamentos

  • Índices

  • Constraints

Exemplo:

IDNOMECIDADE
1ANASÃO PAULO
2JOÃOSANTOS
3MARIARIO

Essa simplicidade aparente esconde uma enorme complexidade de armazenamento.


SUA PRIMEIRA CONSULTA DE VERDADE

O erro mais comum é usar:

SELECT *
FROM CLIENTES;

Em produção isso costuma ser um desastre.

O profissional experiente utiliza:

SELECT
    ID,
    NOME,
    CIDADE
FROM CLIENTES;

Por quê?

Porque reduz:

  • I/O

  • CPU

  • Network Traffic

  • Uso de buffer pools

No DB2 13 isso continua sendo uma das melhores práticas.


APRENDENDO A FILTRAR DADOS

O poder real surge com o WHERE.

SELECT
    NOME
FROM CLIENTES
WHERE CIDADE = 'SANTOS';

Sem WHERE:

SCAN TOTAL

Com WHERE:

BUSCA DIRECIONADA

Diferença gigantesca.

Principalmente em tabelas com bilhões de linhas.


OPERADORES MAIS UTILIZADOS

Igualdade

WHERE ID = 100

Diferente

WHERE ID <> 100

Maior

WHERE SALARIO > 10000

Menor

WHERE SALARIO < 5000

Intervalo

WHERE SALARIO
BETWEEN 5000 AND 10000

Lista

WHERE CIDADE
IN ('SANTOS','CAMPINAS')

LIKE: A ARMA SECRETA DOS ANALISTAS

SELECT *
FROM CLIENTES
WHERE NOME LIKE 'MAR%';

Retorna:

  • MARIA

  • MARCOS

  • MARCELO

Mas atenção.

LIKE mal utilizado pode destruir a performance.

Exemplo ruim:

LIKE '%MAR%'

O otimizador normalmente perde a possibilidade de usar índices eficientemente.


ORDER BY

Organizando resultados.

SELECT
NOME,
SALARIO
FROM FUNCIONARIOS
ORDER BY SALARIO DESC;

Maior salário primeiro.

Muito simples.

Muito poderoso.

Muito custoso quando mal utilizado.


DISTINCT

Eliminando duplicidades.

SELECT DISTINCT
CIDADE
FROM CLIENTES;

Resultado:

SANTOS
CAMPINAS
RIO

Sem repetições.


CONTANDO REGISTROS

Todo DBA utiliza:

SELECT COUNT(*)
FROM CLIENTES;

Mas poucos iniciantes sabem que em tabelas gigantes isso pode gerar leituras enormes.

Por isso estatísticas e catálogos do DB2 também são utilizados para estimativas.


FUNÇÕES DE AGREGAÇÃO

Soma

SELECT SUM(VALOR)
FROM VENDAS;

Média

SELECT AVG(SALARIO)
FROM FUNCIONARIOS;

Máximo

SELECT MAX(SALARIO)
FROM FUNCIONARIOS;

Mínimo

SELECT MIN(SALARIO)
FROM FUNCIONARIOS;

GROUP BY: ONDE O SQL COMEÇA A FICAR INTERESSANTE

Exemplo:

SELECT
CIDADE,
COUNT(*)
FROM CLIENTES
GROUP BY CIDADE;

Resultado:

CidadeQuantidade
Santos1200
São Paulo5800
Campinas900

Aqui começamos a transformar dados em informação.


HAVING

Filtrando grupos.

SELECT
CIDADE,
COUNT(*)
FROM CLIENTES
GROUP BY CIDADE
HAVING COUNT(*) > 1000;

Somente cidades relevantes aparecem.


JOINS: O SUPERPODER DO SQL

Aqui nasce o verdadeiro banco relacional.

Tabela CLIENTES:

IDNOME
1ANA

Tabela PEDIDOS:

PEDIDOID_CLIENTE
1001

Consulta:

SELECT
C.NOME,
P.PEDIDO
FROM CLIENTES C
INNER JOIN PEDIDOS P
ON C.ID = P.ID_CLIENTE;

Resultado:

ANA 100

Magia?

Não.

Modelo relacional.


INNER JOIN

Retorna apenas correspondências.

INNER JOIN

É o JOIN mais utilizado do mundo.


LEFT JOIN

Mantém todos os registros da esquerda.

LEFT JOIN

Mesmo sem correspondência.

Muito usado em auditorias.


SUBSELECTS

Uma consulta dentro da outra.

SELECT *
FROM FUNCIONARIOS
WHERE SALARIO >
(
SELECT AVG(SALARIO)
FROM FUNCIONARIOS
);

Funcionários acima da média.

Excelente exemplo de lógica relacional.


SQL E COBOL: UMA DUPLA IMBATÍVEL

Em Mainframe o SQL raramente vive sozinho.

Exemplo Embedded SQL:

EXEC SQL
SELECT NOME
INTO :WS-NOME
FROM CLIENTES
WHERE ID = :WS-ID
END-EXEC.

Esse padrão movimenta bancos, seguradoras, governos e bolsas de valores há décadas.


O PAPEL DO BIND

Iniciantes aprendem SQL.

Profissionais Mainframe aprendem:

  • Pré-compilação

  • DBRM

  • PACKAGE

  • PLAN

  • BIND

Sem isso o SQL não chega à produção.


O OTIMIZADOR: O CÉREBRO DO DB2

O usuário escreve:

SELECT *
FROM CLIENTES
WHERE ID = 100;

O DB2 pergunta:

  • Uso índice?

  • Faço scan?

  • Quantas páginas?

  • Quanto CPU?

Esse processo é chamado:

Access Path Selection

É aqui que a mágica acontece.


EXPLAIN: O RAIO-X DA CONSULTA

Nunca confie apenas porque uma consulta funciona.

Verifique o plano.

EXPLAIN PLAN FOR
SELECT *
FROM CLIENTES;

O DB2 mostrará:

  • Índices usados

  • Custo estimado

  • Estratégias de acesso

DBAs vivem nessa análise.


O QUE MUDA NO DB2 13?

O DB2 13 trouxe avanços importantes:

Melhor exploração de estatísticas

O otimizador toma decisões mais inteligentes.

Melhor uso de CPU

Redução de consumo em workloads intensos.

Aprimoramentos em SQL Analytics

Funções analíticas mais eficientes.

Melhor integração híbrida

Conectividade moderna com APIs e aplicações distribuídas.

Evolução contínua do Machine Learning para otimização

Capacidade crescente de melhorar decisões de acesso com base em padrões observados.


ERROS CLÁSSICOS DOS INICIANTES

SELECT *

Evite.


Falta de índice

Performance despenca.


WHERE inadequado

Full table scan.


JOIN sem critério

Explosão de registros.


UPDATE sem WHERE

O terror dos DBAs.

UPDATE CLIENTES
SET STATUS='A';

Toda tabela alterada.

Acidente clássico.


O CAMINHO PARA VIRAR ESPECIALISTA

Etapa 1

Dominar SELECT.


Etapa 2

Dominar filtros.


Etapa 3

Dominar JOINs.


Etapa 4

Entender índices.


Etapa 5

Aprender EXPLAIN.


Etapa 6

Estudar catálogo DB2.


Etapa 7

Entender RUNSTATS.


Etapa 8

Compreender Access Paths.


Etapa 9

SQL embarcado em COBOL.


Etapa 10

Otimização avançada.


CONCLUSÃO: SQL É A NOVA LINGUAGEM UNIVERSAL DO MAINFRAME

Muitos profissionais acreditam que dominar COBOL é suficiente para trabalhar em Mainframe.

Não é.

O mercado moderno exige uma combinação poderosa:

  • COBOL

  • JCL

  • CICS

  • RACF

  • DB2

  • SQL

E dentro desse conjunto, SQL ocupa uma posição privilegiada.

Toda aplicação corporativa depende dele.

Toda API consulta dados através dele.

Toda IA corporativa precisa dele.

Todo analista precisa entendê-lo.

O segredo não é decorar comandos.

O segredo é compreender o que acontece por trás deles.

Quando você entende como o DB2 13 interpreta uma consulta, escolhe índices, calcula custos, acessa páginas e otimiza recursos, deixa de ser apenas alguém que escreve SQL.

Você passa a pensar como o próprio banco de dados.

E, no universo Bellacosa Mainframe, é exatamente aí que começa a verdadeira jornada: não em aprender comandos, mas em aprender a conversar com um dos sistemas mais sofisticados já construídos pela engenharia da computação.

☕🚀 Bem-vindo ao mundo do DB2 13. O primeiro SELECT é simples. O desafio real é transformar consultas em performance, conhecimento e valor para o negócio.


domingo, 23 de janeiro de 2022

SPUFI sem Mistérios: do Primeiro SELECT ao Dataset de Saída no Db2 for z/OS

 

Bellacosa Mainframe e o spufi sem misterios

☕ Um Café no Bellacosa Mainframe

SPUFI sem Mistérios: do Primeiro SELECT ao Dataset de Saída no Db2 for z/OS

O guia do programador COBOL Padawan para entender SQL, datasets, isolamento, CCSID, commit, JCL e tudo o que acontece por trás da tela verde

Imagine a cena.

Você acabou de entrar no TSO, abriu o ISPF, navegou até o DB2I e escolheu a opção SPUFI. Diante de você aparece aquela clássica tela preta, com letras verdes e azuis, campos numerados e algumas opções que parecem inocentes:

EDIT INPUT  . . . . ===> YES
EXECUTE . . . . . . ===> YES
AUTOCOMMIT . . . . . ===> YES
BROWSE OUTPUT  . . . ===> YES

O programador COBOL Padawan olha para aquilo e pensa:

“Eu só queria executar um SELECT. Por que preciso informar dataset, volume, senha, isolamento, formato, espaço primário, espaço secundário, LRECL, BLKSIZE e CCSID?”

Essa pergunta é perfeita.

Ela revela uma diferença fundamental entre o mundo distribuído e o universo IBM Mainframe.

Em muitas ferramentas modernas, você abre uma janela, digita SQL e recebe o resultado em uma grade gráfica. No z/OS, entretanto, cada etapa foi construída para ser explícita, controlável, auditável e reutilizável. O SPUFI não trabalha apenas com uma “caixa de texto”. Ele trabalha com datasets reais, parâmetros de execução, formatos de registro, controle transacional e integração direta com o subsistema Db2.

O SPUFI é simples na aparência, mas por trás daquela tela existe uma pequena cadeia de processamento digna de uma aplicação batch.

Prepare o café, abra o caderno de anotações e ajuste os óculos de programador Jedi. Vamos desmontar o SPUFI peça por peça.


Bellacosa Mainframe o que é o Spufi?

1. O que é SPUFI?

SPUFI significa:

SQL Processor Using File Input

Em uma tradução livre:

Processador SQL usando um arquivo como entrada.

Esse nome descreve exatamente o que a ferramenta faz.

O SPUFI:

  1. lê comandos SQL de um dataset;

  2. envia esses comandos ao Db2;

  3. recebe o resultado;

  4. grava as mensagens e linhas retornadas em outro dataset;

  5. opcionalmente abre o resultado para consulta.

Seu fluxo básico é:

Programador
    |
    v
Dataset com SQL
    |
    v
SPUFI
    |
    v
Plano/Pacote do DB2I
    |
    v
Subsistema Db2
    |
    v
Parser + Otimizador + Executor
    |
    v
Dataset de saída

Perceba um detalhe importante: o SPUFI não é o banco de dados, nem o otimizador e nem o mecanismo responsável por acessar as tabelas.

Ele é uma interface.

Quem realmente valida, otimiza e executa o SQL é o Db2.


2. Por que o SPUFI continua importante?

Mesmo existindo ferramentas gráficas, IDEs, plugins para VS Code, interfaces web e utilitários distribuídos, o SPUFI continua extremamente útil porque:

  • executa SQL diretamente dentro do ambiente z/OS;

  • usa a autenticação do usuário TSO;

  • acessa o subsistema Db2 local;

  • não depende de configuração ODBC ou JDBC externa;

  • grava a entrada e a saída em datasets;

  • facilita auditoria e repetição dos testes;

  • funciona bem em ambientes restritos;

  • é familiar para DBAs, sysprogs e desenvolvedores veteranos.

Além disso, o SPUFI é uma excelente escola.

Quem aprende SPUFI acaba aprendendo, mesmo sem perceber:

  • PDS e membros;

  • datasets sequenciais;

  • atributos DCB;

  • alocação em DASD;

  • CCSID;

  • terminadores SQL;

  • níveis de isolamento;

  • commits;

  • planos e pacotes;

  • códigos SQL;

  • organização de scripts.

Portanto, o SPUFI não é apenas uma ferramenta antiga. Ele é uma ponte entre SQL e a cultura operacional do mainframe.


3. A primeira tela: o painel principal do SPUFI

Na tela mostrada, temos algo semelhante a:

SPUFI                                         SSID: DB9G

Enter the input data set name:
 1 DATA SET NAME ... ===> 'IBMUSER.WORKBOOK.SQL(SELCOPA)'
 2 VOLUME SERIAL .... ===>
 3 DATA SET PASSWORD  ===>

Enter the output data set name:
 4 DATA SET NAME ... ===> 'INEFE00.OUTPUT.SAIDA'

Specify processing options:
 5 CHANGE DEFAULTS .. ===> YES
 6 EDIT INPUT ....... ===> YES
 7 EXECUTE .......... ===> YES
 8 AUTOCOMMIT ....... ===> YES
 9 BROWSE OUTPUT .... ===> YES

For remote SQL processing:
10 CONNECT LOCATION . ===>

No canto superior direito aparece:

SSID: DB9G

SSID significa Subsystem Identifier.

É o identificador do subsistema Db2 ao qual o DB2I está conectado.

Em uma instalação, podem existir vários subsistemas:

DB2D   Desenvolvimento
DB2T   Testes
DB2H   Homologação
DB2P   Produção
DB9G   Laboratório ou ambiente específico

O nome não possui significado universal. Cada empresa define sua convenção.

Um Padawan deve sempre observar o SSID antes de executar qualquer comando destrutivo.

Um DELETE no ambiente errado pode transformar uma aula tranquila em uma reunião extraordinária com DBA, gestor, auditoria, segurança e provavelmente alguém perguntando por que não havia WHERE.


4. Campo 1 — DATA SET NAME de entrada

No exemplo:

'IBMUSER.WORKBOOK.SQL(SELCOPA)'

Esse nome possui duas partes:

IBMUSER.WORKBOOK.SQL

É o dataset.

SELCOPA

É o membro.

Isso indica que o dataset provavelmente é um PDS ou PDSE.

Podemos visualizá-lo como uma pasta:

IBMUSER.WORKBOOK.SQL
   |
   +-- SELCOPA
   +-- SELCLIENT
   +-- UPDTEST
   +-- CREATE01
   +-- JOIN001

Cada membro contém um ou mais comandos SQL.

Por exemplo, o membro SELCOPA pode conter:

SELECT EMPNO,
       FIRSTNME,
       LASTNAME,
       WORKDEPT
  FROM DSN8C10.EMP
 WHERE WORKDEPT = 'A00'
 ORDER BY LASTNAME;

Por que usar um PDS ou PDSE?

Porque ele permite organizar vários scripts dentro do mesmo dataset.

Uma estrutura interessante seria:

IBMUSER.DB2.SQL
   |
   +-- SEL001
   +-- SEL002
   +-- INS001
   +-- UPD001
   +-- DEL001
   +-- DDL001
   +-- EXPLAIN
   +-- CATALOG

É como possuir uma biblioteca de scripts SQL, só que usando a estrutura tradicional do z/OS.

PDS ou PDSE?

Os dois funcionam, mas o PDSE costuma ser preferível em ambientes modernos porque:

  • não exige compressão;

  • reutiliza espaço interno de forma mais eficiente;

  • possui melhor gerenciamento de diretório;

  • reduz alguns problemas clássicos de fragmentação.


5. Criando o dataset de entrada

Você pode criar o dataset pelo ISPF 3.2 ou por JCL.

Exemplo:

//CRIASQL  JOB (ACCT),'CRIA PDS SQL',
//             CLASS=A,
//             MSGCLASS=X,
//             NOTIFY=&SYSUID
//*
//ALLOC    EXEC PGM=IEFBR14
//SQLLIB   DD  DSN=IBMUSER.WORKBOOK.SQL,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(TRK,(2,2,20)),
//             DCB=(DSORG=PO,RECFM=FB,LRECL=80,BLKSIZE=0)
//

Agora vamos explicar cada linha.

JOB

//CRIASQL  JOB (ACCT),'CRIA PDS SQL',

Define o início do job.

  • CRIASQL é o nome do job;

  • (ACCT) é a informação contábil;

  • 'CRIA PDS SQL' é uma descrição.

CLASS

//             CLASS=A,

Indica a classe de execução.

A classe controla aspectos como:

  • fila;

  • prioridade;

  • recursos;

  • regras locais de execução.

MSGCLASS

//             MSGCLASS=X,

Indica a classe de saída das mensagens JES.

NOTIFY

//             NOTIFY=&SYSUID

Solicita que o usuário que submeteu o job seja notificado quando ele terminar.

EXEC PGM=IEFBR14

//ALLOC    EXEC PGM=IEFBR14

IEFBR14 é um programa praticamente vazio, tradicionalmente usado para permitir que o sistema processe instruções DD.

Ele não “cria” o dataset diretamente. Quem faz a alocação é o gerenciamento de datasets do z/OS ao interpretar a DD com DISP=NEW.

Esse é um dos grandes easter eggs do mainframe: um programa que praticamente não faz nada tornou-se uma das peças mais famosas do JCL.

DSN

//SQLLIB   DD  DSN=IBMUSER.WORKBOOK.SQL,

Define o nome do dataset.

DISP

//             DISP=(NEW,CATLG,DELETE),

Significa:

  • NEW: o dataset será criado;

  • CATLG: se o step terminar normalmente, será catalogado;

  • DELETE: se houver falha, será excluído.

UNIT

//             UNIT=SYSDA,

Solicita uma unidade DASD genérica.

SPACE

//             SPACE=(TRK,(2,2,20)),

Significa:

  • unidade de alocação: tracks;

  • espaço primário: 2 tracks;

  • espaço secundário: 2 tracks;

  • diretório: 20 blocos.

O terceiro valor é relevante porque o dataset é particionado.

DCB

//             DCB=(DSORG=PO,RECFM=FB,LRECL=80,BLKSIZE=0)
  • DSORG=PO: organização particionada;

  • RECFM=FB: registros fixos blocados;

  • LRECL=80: cada registro possui 80 bytes;

  • BLKSIZE=0: o sistema escolhe um tamanho de bloco adequado.

O formato FB 80 é clássico para código-fonte, JCL e scripts SQL.


6. Campo 2 — VOLUME SERIAL

VOLUME SERIAL ===>

Esse campo normalmente fica em branco quando o dataset está catalogado.

O catálogo do z/OS já informa em qual volume ele reside.

Você só precisa preencher o VOLSER quando trabalha com um dataset não catalogado ou quando há uma razão operacional específica.

Exemplo:

VOLUME SERIAL ===> VOL001

Na maioria dos ambientes modernos, deixar em branco é correto.


7. Campo 3 — DATA SET PASSWORD

DATA SET PASSWORD ===>

Esse campo remete a mecanismos antigos de proteção por senha de dataset.

Atualmente, o acesso normalmente é controlado por um produto de segurança como:

  • RACF;

  • ACF2;

  • Top Secret.

Em ambientes modernos, esse campo quase sempre permanece vazio.

É quase uma peça arqueológica viva: continua presente porque o mainframe preserva compatibilidade com décadas de história.


8. Campo 4 — dataset de saída

No exemplo:

'INEFE00.OUTPUT.SAIDA'

A tela informa:

Must be a sequential data set

Isso significa que o dataset de saída deve ser sequencial.

O SPUFI grava:

  • o SQL executado;

  • mensagens do Db2;

  • SQLCODE;

  • SQLSTATE;

  • linhas retornadas;

  • quantidade de registros;

  • informações de commit;

  • eventuais erros.

Exemplo de saída:

---------+---------+---------+---------+---------+---------

SELECT EMPNO, FIRSTNME, LASTNAME
FROM DSN8C10.EMP
WHERE WORKDEPT = 'A00';

EMPNO  FIRSTNME     LASTNAME
------ ------------ ---------------
000010 CHRISTINE    HAAS
000110 VINCENZO     LUCCHESSI
000120 SEAN         O'CONNELL

DSNE610I NUMBER OF ROWS DISPLAYED IS 3
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0

Criando o dataset de saída

//CRIAOUT  JOB (ACCT),'CRIA SAIDA SPUFI',
//             CLASS=A,
//             MSGCLASS=X,
//             NOTIFY=&SYSUID
//*
//ALLOC    EXEC PGM=IEFBR14
//OUTPUT   DD  DSN=IBMUSER.OUTPUT.SPUFI,
//             DISP=(NEW,CATLG,DELETE),
//             UNIT=SYSDA,
//             SPACE=(TRK,(5,5)),
//             DCB=(DSORG=PS,RECFM=VB,LRECL=4092,BLKSIZE=0)
//

Aqui temos:

DSORG=PS

Physical Sequential, ou seja, sequencial.

RECFM=VB

Registros variáveis e blocados.

LRECL=4092

Permite linhas grandes de saída.

BLKSIZE=0

O sistema calcula um valor apropriado.


9. Campo 5 — CHANGE DEFAULTS

CHANGE DEFAULTS ===> YES

Com YES, o SPUFI abre a tela de parâmetros padrão.

Com NO, utiliza os valores já salvos no perfil do usuário ou na configuração da instalação.

Essa opção é útil quando você precisa alterar:

  • nível de isolamento;

  • número máximo de linhas;

  • terminador SQL;

  • atributos do dataset de saída;

  • largura das colunas;

  • formato dos cabeçalhos.

Para uma consulta simples, você pode usar NO.

Para aprender ou ajustar comportamento, use YES.


10. Campo 6 — EDIT INPUT

EDIT INPUT ===> YES

Com YES, o SPUFI abre o membro de entrada no editor ISPF antes da execução.

O fluxo será:

SPUFI
  |
  +--> abre ISPF Edit
  |
  +--> você grava o SQL
  |
  +--> pressiona PF3
  |
  +--> SPUFI executa

Com NO, ele executa diretamente o conteúdo atual do dataset.

Isso é útil quando o script já está pronto e não precisa ser revisado.

Exemplo de SQL para iniciantes

SELECT CURRENT DATE,
       CURRENT TIME,
       CURRENT TIMESTAMP
  FROM SYSIBM.SYSDUMMY1;

A tabela SYSIBM.SYSDUMMY1 é uma tabela especial com uma única linha, muito usada para testar expressões.

É o equivalente Db2 de uma pequena bancada de laboratório.


11. Campo 7 — EXECUTE

EXECUTE ===> YES

Com YES, o SQL será enviado ao Db2.

Com NO, o SPUFI pode permitir que você apenas edite o input sem executar.

Parece inútil, mas é interessante quando o SPUFI está sendo usado apenas como uma forma rápida de localizar e modificar um membro SQL.


12. Campo 8 — AUTOCOMMIT

AUTOCOMMIT ===> YES

Esse é um dos campos mais perigosos da tela.

Com YES, o SPUFI confirma automaticamente uma unidade de trabalho bem-sucedida.

Exemplo:

UPDATE CORP.CLIENTE
   SET STATUS = 'I'
 WHERE CLIENTE_ID = 100;

Se o comando funcionar e AUTOCOMMIT=YES, a alteração será confirmada.

Um ROLLBACK posterior não desfará essa atualização.

Para SELECT

Em consultas, o risco é pequeno.

Para INSERT, UPDATE e DELETE

Atenção máxima.

Durante testes, uma prática mais segura é:

AUTOCOMMIT ===> NO

E incluir comandos explícitos:

UPDATE CORP.CLIENTE
   SET STATUS = 'I'
 WHERE CLIENTE_ID = 100;

SELECT CLIENTE_ID,
       STATUS
  FROM CORP.CLIENTE
 WHERE CLIENTE_ID = 100;

ROLLBACK;

Assim você verifica o resultado e depois desfaz.

Quando estiver absolutamente certo:

UPDATE CORP.CLIENTE
   SET STATUS = 'I'
 WHERE CLIENTE_ID = 100;

COMMIT;

Cuidado especial com DELETE

Nunca execute casualmente:

DELETE FROM CORP.CLIENTE;

Sem WHERE, todas as linhas elegíveis podem ser removidas.

Antes de executar um DELETE, transforme-o em SELECT:

SELECT *
  FROM CORP.CLIENTE
 WHERE STATUS = 'I';

Confira a quantidade.

Depois:

DELETE
  FROM CORP.CLIENTE
 WHERE STATUS = 'I';

Esse pequeno ritual salva carreiras.


13. Campo 9 — BROWSE OUTPUT

BROWSE OUTPUT ===> YES

Com YES, o dataset de saída é aberto automaticamente após a execução.

Com NO, o resultado é gravado, mas você precisará abri-lo manualmente.

Por exemplo, usando:

ISPF 3.4

ou um comando:

BROWSE 'IBMUSER.OUTPUT.SPUFI'

Usar YES é conveniente para testes interativos.

Usar NO pode ser útil quando o resultado é muito grande ou quando o processamento será revisado posteriormente.


14. Campo 10 — CONNECT LOCATION

CONNECT LOCATION ===>

Esse campo permite direcionar a execução para uma localização Db2 remota.

Em ambientes distribuídos, o Db2 pode usar DRDA para comunicação entre subsistemas.

Exemplo conceitual:

Db2 local DB2D
     |
     | DRDA
     v
Db2 remoto DB2P

O valor usado depende da configuração de localização no catálogo Db2.

Para consultas locais, deixe em branco.


15. O aviso DSNE345I e a guerra dos CCSIDs

Na segunda tela aparece:

DSNE345I WARNING: DB2 DATA CORRUPTION CAN RESULT
FROM THIS SPUFI SESSION BECAUSE THE
CCSID USED BY THE TERMINAL IS NOT THE
SAME AS THE CCSID USED BY SPUFI

TERMINAL CCSID: 37
SPUFI CCSID   : 1047

Esse não é um simples aviso cosmético.

CCSID significa:

Coded Character Set Identifier

Ele identifica a tabela de codificação de caracteres.

No mundo z/OS, “EBCDIC” não é uma única tabela universal. Existem diferentes variantes.

Entre elas:

  • CCSID 37;

  • CCSID 500;

  • CCSID 1047;

  • CCSID 1140.

O terminal está usando CCSID 37, enquanto o SPUFI espera 1047.

Caracteres alfabéticos simples podem aparecer corretamente, mas símbolos especiais podem ocupar posições diferentes.

Os maiores suspeitos são caracteres como:

[
]
{
}
|
\
^
~

Imagine uma expressão SQL com texto:

INSERT INTO TESTE.TABELA
       (DESCRICAO)
VALUES ('ARQUIVO [TEMP]');

Se houver conversão incorreta, os colchetes podem ser gravados como outros símbolos.

Em um SELECT, você pode apenas ver uma saída estranha.

Em um INSERT ou UPDATE, porém, dados incorretos podem ser persistidos.

O que fazer?

O aviso diz:

NOTIFY THE DB2 SYSTEM ADMINISTRATOR

Isso significa que a solução definitiva normalmente envolve revisar:

  • configuração do emulador 3270;

  • code page da sessão;

  • parâmetros do DB2I;

  • CCSID do subsistema;

  • perfil do usuário;

  • configuração do SPUFI.

No emulador TN3270, procure opções relacionadas a:

  • host code page;

  • EBCDIC code page;

  • character set;

  • CCSID;

  • language;

  • keyboard mapping.

Não altere aleatoriamente em produção. Uma mudança incorreta pode resolver um símbolo e quebrar outro.


16. A tela CURRENT SPUFI DEFAULTS

A terceira tela apresenta os parâmetros internos do SPUFI.

CURRENT SPUFI DEFAULTS

Vamos examinar cada um.


17. SQL TERMINATOR

SQL TERMINATOR ===> ;

O ponto e vírgula indica o fim de cada instrução SQL.

Exemplo:

SELECT COUNT(*)
  FROM SYSIBM.SYSTABLES;

Vários comandos:

SELECT CURRENT DATE
  FROM SYSIBM.SYSDUMMY1;

SELECT CURRENT TIME
  FROM SYSIBM.SYSDUMMY1;

Alterando o terminador

Em alguns scripts, especialmente com rotinas SQL PL, o ponto e vírgula também aparece dentro de blocos.

Pode ser conveniente trocar o terminador externo:

SQL TERMINATOR ===> #

Então:

CREATE PROCEDURE TESTE.PROC1()
LANGUAGE SQL
BEGIN
    INSERT INTO TESTE.LOG
    VALUES (CURRENT TIMESTAMP);

    UPDATE TESTE.CONTROLE
       SET STATUS = 'F';
END
#

O # encerra a instrução completa, enquanto os pontos e vírgulas continuam dentro do bloco.


18. ISOLATION LEVEL

Na tela:

ISOLATION LEVEL ===> CS

Os valores mais comuns são:

UR
CS
RS
RR

UR — Uncommitted Read

É a leitura com menor compromisso de consistência.

Permite ler dados que outra transação modificou, mas ainda não confirmou.

Exemplo:

SELECT *
  FROM CORP.MOVIMENTO
 WITH UR;

Vantagens:

  • poucos locks;

  • boa concorrência;

  • útil para relatórios não críticos.

Riscos:

  • dirty read;

  • dados podem desaparecer após rollback;

  • totais podem não representar um estado confirmado.

Use UR para consultas informativas, nunca como base cega para decisões financeiras ou atualizações dependentes.

CS — Cursor Stability

É o valor mostrado na tela.

O Db2 protege a linha atualmente posicionada pelo cursor e libera locks conforme a navegação, dependendo do plano e da execução.

É um bom equilíbrio entre:

  • consistência;

  • concorrência;

  • desempenho.

É muito comum em aplicações online.

RS — Read Stability

Garante maior estabilidade para as linhas qualificadas já lidas.

Evita que elas sejam modificadas de forma conflitante durante a unidade de trabalho.

Pode manter mais locks.

RR — Repeatable Read

É o nível mais restritivo.

A mesma consulta dentro da unidade de trabalho tende a reencontrar um conjunto estável de linhas, de acordo com as regras do isolamento.

Pode gerar:

  • muitos locks;

  • contenção;

  • timeout;

  • deadlock;

  • escalonamento de locks.

Comparação conceitual

IsolamentoConsistênciaConcorrênciaLocks
URbaixamuito altamínimos
CSequilibradaaltamoderados
RSaltamédiamaiores
RRmuito altamenorelevados

19. MAX SELECT LINES

MAX SELECT LINES ===> 250

Esse parâmetro limita a quantidade de linhas exibidas pelo SPUFI.

Ele funciona como um cinto de segurança.

Imagine:

SELECT *
  FROM SYSIBM.SYSCOLUMNS;

Dependendo do ambiente, isso pode retornar milhares de linhas.

O SPUFI interrompe a exibição ao atingir o limite configurado.

Atenção: isso não significa necessariamente que o Db2 sempre acessará apenas 250 linhas em todas as circunstâncias. O limite controla principalmente o processamento e apresentação do resultado pelo SPUFI.

Para consultas grandes, prefira filtros:

SELECT NAME,
       CREATOR,
       TYPE
  FROM SYSIBM.SYSTABLES
 WHERE CREATOR = 'IBMUSER'
 ORDER BY NAME;

20. ALLOW SQL WARNINGS

ALLOW SQL WARNINGS ===> NO

SQL warnings são avisos que não representam necessariamente falha fatal.

O SQLCA pode trazer:

SQLCODE positivo

Exemplos comuns incluem:

  • truncamento;

  • eliminação de valores nulos em agregações;

  • nenhuma linha em certas operações;

  • condições especiais de processamento.

Com NO, o SPUFI pode interromper ou tratar de maneira mais conservadora.

Com YES, ele pode continuar buscando linhas após avisos.

Para aprendizado, deixar NO ajuda a perceber que algo especial ocorreu.


21. CHANGE PLAN NAMES

CHANGE PLAN NAMES ===> NO

O SPUFI executa sob estruturas Db2 previamente definidas, incluindo planos e pacotes do DB2I.

Essa opção permite trabalhar com nomes alternativos em configurações específicas.

Para o programador iniciante, a recomendação é manter:

NO

Alterar planos exige conhecimento de:

  • BIND;

  • PACKAGE;

  • PLAN;

  • COLLECTION;

  • autorização;

  • compatibilidade do ambiente.


22. SQL FORMAT

SQL FORMAT ===> SQL

Esse campo define o tratamento do conteúdo SQL.

As opções podem variar conforme versão e configuração, mas geralmente distinguem formatos como:

  • SQL convencional;

  • SQL com comentários;

  • SQL PL.

Para consultas normais:

SQL

é suficiente.


23. SPACE UNIT

SPACE UNIT ===> TRK

Define a unidade usada para alocar o dataset de saída.

Valores comuns:

TRK
CYL

TRK significa track.

CYL significa cylinder.

Para resultados pequenos, tracks são suficientes.

Para saídas muito grandes, cylinders podem ser mais apropriados.


24. PRIMARY SPACE e SECONDARY SPACE

PRIMARY SPACE   ===> 6
SECONDARY SPACE ===> 5

O espaço primário é alocado inicialmente.

O secundário é solicitado quando o espaço inicial se esgota.

Neste exemplo:

SPACE=(TRK,(6,5))

Conceitualmente:

  • aloque 6 tracks inicialmente;

  • quando necessário, expanda em blocos de 5 tracks.

Muitas extensões pequenas podem causar fragmentação e atingir limites de extents.

Por outro lado, uma alocação primária exagerada desperdiça espaço.

O tamanho ideal depende do volume esperado.


25. RECORD LENGTH

RECORD LENGTH ===> 4092

É o LRECL do dataset de saída.

Como o resultado pode incluir colunas extensas, o SPUFI usa registros largos.

Um VARCHAR(2000) ou a combinação de várias colunas pode exigir linhas grandes.

Se o LRECL for pequeno demais, a saída pode ser truncada ou a alocação pode falhar, dependendo do cenário.


26. BLOCK SIZE

BLOCK SIZE ===> 4096

O BLKSIZE indica o tamanho dos blocos físicos usados na gravação.

Blocos reduzem a quantidade de operações de I/O.

Em alocações modernas, frequentemente usamos:

BLKSIZE=0

para permitir que o sistema determine um valor eficiente.

Na tela do SPUFI, valores predefinidos podem ser usados conforme a configuração local.


27. RECORD FORMAT

RECORD FORMAT ===> VB

VB significa:

Variable Blocked

Os registros possuem tamanho variável e são agrupados em blocos.

Isso é apropriado para resultados SQL, porque uma linha pode ter 20 bytes e outra 800 bytes.

Outros formatos citados na tela:

F
FB
FBA
V
VB
VBA
  • F: fixo;

  • FB: fixo blocado;

  • FBA: fixo blocado com controle ASA;

  • V: variável;

  • VB: variável blocado;

  • VBA: variável blocado com controle ASA.


28. DEVICE TYPE

DEVICE TYPE ===> SYSDA

SYSDA é um nome genérico de unidade DASD.

O sistema e o SMS determinam o volume apropriado.

Em ambientes gerenciados por SMS, vários parâmetros físicos podem ser escolhidos automaticamente por classes de armazenamento.


29. MAX NUMERIC FIELD

MAX NUMERIC FIELD ===> 33

Define a largura máxima usada para apresentar campos numéricos.

Isso evita que números muito extensos destruam o alinhamento da saída.

Por exemplo:

SELECT DECIMAL(12345678901234567890,20,0)
  FROM SYSIBM.SYSDUMMY1;

A configuração controla quanto espaço poderá ser reservado para exibição.


30. MAX CHAR FIELD

MAX CHAR FIELD ===> 80

Define a largura máxima de apresentação das colunas de caracteres.

Imagine uma coluna:

DESCRICAO VARCHAR(1000)

Sem limite, uma única coluna tornaria a saída enorme.

Com máximo 80, a apresentação fica mais administrável.

Atenção: isso pode significar que você não verá todo o conteúdo visualmente na linha formatada.

Quando precisar analisar o valor integral, selecione a coluna isoladamente ou use funções como:

SELECT LENGTH(DESCRICAO),
       SUBSTR(DESCRICAO,1,200)
  FROM TESTE.PRODUTO;

31. COLUMN HEADING

COLUMN HEADING ===> NAMES

Opções comuns:

NAMES
LABELS
ANY
BOTH

NAMES

Usa o nome técnico da coluna.

CUST_ID
CUST_NAME

LABELS

Usa o label definido no catálogo, se existir.

Código do Cliente
Nome do Cliente

BOTH

Pode mostrar nome e label.

Para desenvolvedores, NAMES costuma ser mais útil porque corresponde ao SQL e ao DCLGEN.

Para relatórios destinados a usuários, labels podem ser mais amigáveis.


32. Primeiro laboratório SPUFI: SELECT simples

Crie um membro chamado TESTE01 com:

SELECT CURRENT SERVER    AS SERVIDOR,
       CURRENT DATE      AS DATA_ATUAL,
       CURRENT TIME      AS HORA_ATUAL,
       CURRENT TIMESTAMP AS TIMESTAMP_ATUAL
  FROM SYSIBM.SYSDUMMY1;

Configure:

EDIT INPUT     YES
EXECUTE        YES
AUTOCOMMIT     YES
BROWSE OUTPUT  YES

Pressione Enter.

O fluxo será:

  1. o SPUFI abre o editor;

  2. você confere o SQL;

  3. pressiona PF3;

  4. o Db2 recebe o comando;

  5. o parser verifica a sintaxe;

  6. o otimizador prepara a execução;

  7. a tabela especial é acessada;

  8. o resultado retorna;

  9. o SPUFI formata a saída;

  10. o dataset de saída é aberto.


33. Segundo laboratório: consultar o catálogo

SELECT CREATOR,
       NAME,
       TYPE
  FROM SYSIBM.SYSTABLES
 WHERE CREATOR = 'IBMUSER'
 ORDER BY NAME;

O catálogo Db2 é um conjunto de tabelas que descreve os objetos do banco.

Ele contém informações sobre:

  • tabelas;

  • colunas;

  • índices;

  • tablespaces;

  • pacotes;

  • planos;

  • privilégios;

  • estatísticas.

Consultar o catálogo é como abrir o mapa interno do reino Db2.


34. Terceiro laboratório: UPDATE seguro com ROLLBACK

SELECT CLIENTE_ID,
       STATUS
  FROM TESTE.CLIENTE
 WHERE CLIENTE_ID = 100;

UPDATE TESTE.CLIENTE
   SET STATUS = 'I'
 WHERE CLIENTE_ID = 100;

SELECT CLIENTE_ID,
       STATUS
  FROM TESTE.CLIENTE
 WHERE CLIENTE_ID = 100;

ROLLBACK;

SELECT CLIENTE_ID,
       STATUS
  FROM TESTE.CLIENTE
 WHERE CLIENTE_ID = 100;

Configure:

AUTOCOMMIT ===> NO

A sequência demonstra:

  1. estado inicial;

  2. alteração;

  3. estado dentro da unidade de trabalho;

  4. rollback;

  5. restauração do valor anterior.

Esse é um excelente laboratório para compreender transações.


35. Executando SQL no Db2 por JCL

O SPUFI é interativo, mas o SQL também pode ser executado em batch usando o utilitário DSNTEP2 ou DSNTEP4, dependendo da instalação.

Exemplo:

//SQLBATCH JOB (ACCT),'EXECUTA SQL',
//             CLASS=A,
//             MSGCLASS=X,
//             NOTIFY=&SYSUID
//*
//STEP01   EXEC PGM=IKJEFT01,DYNAMNBR=20
//STEPLIB  DD  DISP=SHR,DSN=DSN.V13R1M0.SDSNLOAD
//SYSTSPRT DD  SYSOUT=*
//SYSPRINT DD  SYSOUT=*
//SYSUDUMP DD  SYSOUT=*
//SYSTSIN  DD  *
  DSN SYSTEM(DB9G)
  RUN PROGRAM(DSNTEP2) PLAN(DSNTEP13) -
      LIB('DSN.V13R1M0.RUNLIB.LOAD')
  END
/*
//SYSIN    DD  *
SELECT CURRENT SERVER,
       CURRENT DATE,
       CURRENT TIME
  FROM SYSIBM.SYSDUMMY1;

SELECT COUNT(*) AS TOTAL_TABELAS
  FROM SYSIBM.SYSTABLES;
/*

IKJEFT01

//STEP01 EXEC PGM=IKJEFT01

IKJEFT01 permite executar comandos TSO em batch.

É como criar uma sessão TSO controlada pelo JCL.

DYNAMNBR

DYNAMNBR=20

Reserva capacidade para alocações dinâmicas.

STEPLIB

//STEPLIB DD DISP=SHR,DSN=DSN.V13R1M0.SDSNLOAD

Aponta para a biblioteca de load modules do Db2.

O nome real varia conforme a instalação.

SYSTSIN

DSN SYSTEM(DB9G)

Inicia o command processor do Db2 e conecta ao subsistema DB9G.

RUN PROGRAM(DSNTEP2)

Executa o programa DSNTEP2.

PLAN(DSNTEP13)

Informa o plano associado.

O nome também varia conforme versão e instalação.

LIB('DSN.V13R1M0.RUNLIB.LOAD')

Informa a biblioteca onde o programa será localizado.

SYSIN

Contém os comandos SQL.

Assim, a lógica lembra o SPUFI:

SPUFI                 DSNTEP2
------                -------
Dataset input         SYSIN
Execução interativa   Execução batch
Dataset output        SYSPRINT
Tela ISPF             JES/SDSF

36. JCL usando SQL em dataset externo

Em vez de escrever SQL dentro do JCL:

//SYSIN DD *
SELECT ...
/*

podemos usar um membro:

//SYSIN DD DISP=SHR,DSN=IBMUSER.WORKBOOK.SQL(SELCOPA)

Job completo:

//SQLBATCH JOB (ACCT),'SQL VIA PDS',
//             CLASS=A,
//             MSGCLASS=X,
//             NOTIFY=&SYSUID
//*
//STEP01   EXEC PGM=IKJEFT01,DYNAMNBR=20
//STEPLIB  DD DISP=SHR,DSN=DSN.V13R1M0.SDSNLOAD
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSTSIN  DD *
  DSN SYSTEM(DB9G)
  RUN PROGRAM(DSNTEP2) PLAN(DSNTEP13) -
      LIB('DSN.V13R1M0.RUNLIB.LOAD')
  END
/*
//SYSIN    DD DISP=SHR,DSN=IBMUSER.WORKBOOK.SQL(SELCOPA)
//

Essa estrutura permite usar o mesmo membro:

  • no SPUFI;

  • em batch;

  • em processos automatizados;

  • em pipelines;

  • em testes de implantação.


37. Erros comuns e possíveis soluções

SQLCODE -204

Objeto não encontrado.

Exemplo:

SQLCODE = -204

Possíveis causas:

  • tabela inexistente;

  • schema incorreto;

  • nome não qualificado;

  • ambiente errado.

Solução:

SELECT CREATOR,
       NAME
  FROM SYSIBM.SYSTABLES
 WHERE NAME = 'CLIENTE';

Use o nome qualificado:

SELECT *
  FROM CORP.CLIENTE;

SQLCODE -206

Coluna não encontrada.

Possíveis causas:

  • erro de digitação;

  • coluna pertence a outra tabela;

  • alias incorreto.

Verifique:

SELECT NAME,
       COLNO,
       COLTYPE
  FROM SYSIBM.SYSCOLUMNS
 WHERE TBNAME = 'CLIENTE'
   AND TBCREATOR = 'CORP';

SQLCODE -104

Erro de sintaxe.

Exemplo incorreto:

SELECT NOME
  CLIENTE;

Faltou FROM.

Correto:

SELECT NOME
  FROM CLIENTE;

SQLCODE -551

Usuário sem autorização.

Pode faltar:

  • SELECT;

  • INSERT;

  • UPDATE;

  • DELETE;

  • EXECUTE;

  • uso de package ou plan.

A solução deve ser tratada com o administrador de segurança ou DBA.

SQLCODE -811

Um SELECT INTO retornou mais de uma linha.

No SPUFI isso aparece principalmente em testes de SQL que posteriormente serão usados em COBOL.

A consulta deveria retornar uma linha, mas encontrou várias.

Use filtro mais seletivo ou cursor.

SQLCODE -911

Rollback causado por deadlock ou timeout.

O Db2 desfez a unidade de trabalho.

Possíveis ações:

  • reduzir duração da transação;

  • acessar tabelas em ordem consistente;

  • melhorar índices;

  • revisar isolamento;

  • executar commit mais frequente;

  • investigar concorrência.

SQLCODE -913

Deadlock ou timeout sem rollback automático completo em certos contextos.

Exige análise semelhante ao -911.


38. SPUFI e programas COBOL

O SQL testado no SPUFI pode ser levado para um programa COBOL.

SPUFI:

SELECT FIRSTNME,
       LASTNAME
  FROM DSN8C10.EMP
 WHERE EMPNO = '000010';

COBOL:

       EXEC SQL
            SELECT FIRSTNME,
                   LASTNAME
              INTO :WS-FIRST-NAME,
                   :WS-LAST-NAME
              FROM DSN8C10.EMP
             WHERE EMPNO = :WS-EMPNO
       END-EXEC.

A diferença está nas host variables:

:WS-FIRST-NAME
:WS-LAST-NAME
:WS-EMPNO

O SPUFI ajuda a validar:

  • nomes de tabela;

  • nomes de coluna;

  • joins;

  • filtros;

  • funções;

  • acesso esperado.

Mas ele não substitui os testes dentro do programa COBOL, porque o programa ainda envolve:

  • tipos de dados;

  • variáveis indicadoras;

  • SQLCA;

  • cursores;

  • commit;

  • lógica de tratamento de erro;

  • concorrência;

  • package e bind.


39. Curiosidades e easter eggs

O SPUFI é mais “batch” do que parece

Apesar de ser usado interativamente, sua lógica é baseada em arquivos de entrada e saída.

Ele se parece com uma pequena rotina batch controlada por painéis ISPF.

O dataset é parte da documentação

Como o SQL permanece salvo no PDS, ele pode servir como:

  • evidência de teste;

  • histórico;

  • material de treinamento;

  • script reutilizável;

  • base de automação.

O catálogo é o “Google interno” do Db2

Quando você não sabe se uma tabela existe, qual é a coluna, quem criou um índice ou qual package está ligado, o catálogo geralmente possui a resposta.

IEFBR14 não cria datasets sozinho

O programa é apenas uma moldura. A alocação ocorre pela interpretação do JCL.

Um SELECT também pode causar impacto

Muitos iniciantes acreditam que SELECT é sempre inofensivo.

Não é.

Um SELECT ruim pode:

  • fazer tablespace scan;

  • consumir CPU;

  • ler milhões de páginas;

  • ocupar buffer pools;

  • segurar locks;

  • gerar sort;

  • afetar outros usuários.

Leitura também é trabalho.

WITH UR não é magia de desempenho

Ele reduz locking de leitura, mas não corrige:

  • falta de índice;

  • predicado não indexável;

  • join ruim;

  • cardinalidade incorreta;

  • estatísticas antigas.


40. Checklist do Padawan antes de pressionar Enter

Antes de executar:

1. Estou no SSID correto?
2. O dataset de entrada é o membro correto?
3. O output pode ser sobrescrito?
4. O AUTOCOMMIT está adequado?
5. Existe UPDATE, DELETE ou INSERT?
6. O WHERE foi revisado?
7. Testei o filtro com SELECT?
8. O limite de linhas está razoável?
9. Existe aviso de CCSID?
10. Estou autorizado a executar isso?

Para comandos destrutivos, acrescente:

11. Tenho backup ou possibilidade de rollback?
12. Sei quantas linhas serão afetadas?
13. A unidade de trabalho está controlada?
14. Estou fora do horário crítico?
15. O DBA precisa ser avisado?

Conclusão

O SPUFI é uma das ferramentas mais didáticas do ecossistema Db2 for z/OS.

Na superfície, ele parece apenas uma tela para executar SQL. Em profundidade, porém, ele ensina quase todo o vocabulário operacional do mainframe:

  • datasets de entrada e saída;

  • PDS, PDSE e membros;

  • arquivos sequenciais;

  • DCB;

  • RECFM;

  • LRECL;

  • BLKSIZE;

  • espaço primário e secundário;

  • terminadores SQL;

  • planos;

  • pacotes;

  • isolamento;

  • commit e rollback;

  • CCSID;

  • catálogo;

  • SQLCODE;

  • execução interativa;

  • execução batch por JCL.

Para o programador COBOL Padawan, dominar o SPUFI é aprender a conversar diretamente com o Db2 antes de colocar o SQL dentro de um programa.

É nele que você experimenta.

É nele que você erra com segurança — desde que o AUTOCOMMIT esteja corretamente configurado.

É nele que você descobre que um SQL aparentemente simples pode esconder acesso a milhões de linhas.

E é nele que você começa a enxergar o banco não apenas como um lugar onde os dados vivem, mas como um sistema completo de armazenamento, concorrência, transações, segurança e otimização.

No mundo Bellacosa Mainframe, a tela verde nunca é apenas uma tela verde.

Cada campo é uma porta.

Cada parâmetro conta uma história.

Cada mensagem DSNE é um mestre antigo tentando impedir que o Padawan corrompa caracteres, bloqueie uma tabela ou execute um DELETE sem WHERE.

E cada SQLCODE 0 é o Db2 dizendo:

EXECUÇÃO CONCLUÍDA.

A FORÇA DO SQL ESTÁ COM VOCÊ.

sábado, 31 de agosto de 2019

O guia do programador COBOL Padawan para dominar DDL, DML, DQL, DCL e TCL como um oficial da Frota Estelar

 

Bellacosa Mainframe e o sql jedi conheça ddl dml dql dcl e tcl

☕ Um Café no Bellacosa Mainframe

SQL sem Mistérios: Muito Além do SELECT

O guia do programador COBOL Padawan para dominar DDL, DML, DQL, DCL e TCL como um oficial da Frota Estelar

Existe um momento na carreira de todo programador COBOL iniciante em que ele abre uma tela do SPUFI, do DB2I, de alguma ferramenta gráfica ou de um terminal SQL, digita:

SELECT * FROM CLIENTES;

pressiona Enter e sente que acabou de assumir o comando da USS Enterprise.

A tabela responde. As linhas aparecem. Os dados estão ali.

Missão cumprida?

Ainda não, jovem Padawan.

O SELECT é apenas a porta principal da nave. SQL é muito maior do que consultar registros. É uma linguagem capaz de construir estruturas, modificar dados, controlar permissões, organizar transações, impedir inconsistências e proteger sistemas inteiros contra falhas.

Em outras palavras: SQL não é apenas o binóculo que permite observar o espaço. É também o estaleiro que constrói a nave, o computador que controla os sistemas, o oficial de segurança que autoriza acessos e o protocolo de emergência que impede a perda da tripulação.

Para quem está entrando no universo do COBOL, especialmente em ambientes com Db2, compreender as categorias dos comandos SQL é uma das fundações mais importantes da carreira.

Neste café, vamos explorar:

  • DDL — Data Definition Language;

  • DML — Data Manipulation Language;

  • DQL — Data Query Language;

  • DCL — Data Control Language;

  • TCL — Transaction Control Language;

  • diferenças importantes entre comandos;

  • riscos comuns;

  • exemplos práticos;

  • SQL dentro de programas COBOL;

  • transações no mainframe;

  • curiosidades históricas;

  • dicas para entrevistas;

  • um roteiro prático de estudos.

Prepare o café, abra o emulador 3270 e ajuste os escudos. Nossa missão começa agora.


1. SQL não significa apenas SELECT

Muita gente aprende SQL de trás para frente.

Primeiro conhece o SELECT, depois descobre os filtros com WHERE, aprende ORDER BY, talvez um JOIN, e passa a acreditar que SQL é apenas uma linguagem de consulta.

Isso acontece porque a consulta é a parte mais visível.

O analista consulta vendas.

O programador consulta clientes.

O auditor consulta movimentações.

O suporte consulta logs.

Mas, antes que qualquer consulta possa acontecer, alguém precisou:

  1. criar a tabela;

  2. definir suas colunas;

  3. escolher os tipos de dados;

  4. criar chaves;

  5. definir restrições;

  6. inserir registros;

  7. conceder permissões;

  8. controlar transações;

  9. criar índices;

  10. planejar recuperação em caso de falha.

Portanto, SQL administra praticamente todo o ciclo de vida de um banco de dados relacional.

Um banco sem comandos de definição não teria tabelas.

Um banco sem comandos de manipulação não teria registros.

Um banco sem consultas não entregaria informação.

Um banco sem controle de acesso seria uma colônia sem escudos.

Um banco sem transações seria um teletransporte que materializa metade da pessoa em cada sala.

SQL é uma linguagem completa de interação com bancos relacionais.


2. Uma breve origem da linguagem SQL

A história do SQL começa na IBM, durante os anos 1970, quando pesquisadores trabalhavam com o modelo relacional proposto por Edgar F. Codd.

Codd apresentou uma nova forma de organizar dados usando relações, que na prática seriam representadas por tabelas.

Em vez de navegar manualmente por estruturas rígidas e ponteiros físicos, o usuário poderia declarar o resultado desejado.

Essa ideia foi revolucionária.

Em uma linguagem procedural tradicional, você descreve cada passo:

  1. abra o arquivo;

  2. leia o registro;

  3. compare o código;

  4. avance;

  5. repita;

  6. grave o resultado.

Em SQL, você declara:

SELECT NOME
FROM CLIENTE
WHERE CODIGO = 100;

Você diz o que deseja.

O banco decide como encontrar.

Essa diferença entre linguagem procedural e declarativa é fundamental para o programador COBOL.

COBOL normalmente descreve o fluxo.

SQL descreve o resultado.

Quando ambos trabalham juntos, temos uma poderosa combinação:

  • COBOL controla a lógica da aplicação;

  • SQL acessa e manipula os dados;

  • Db2 escolhe o plano de acesso;

  • o sistema operacional garante execução, segurança e recuperação.

É quase como uma equipe da ponte de comando:

  • COBOL é o capitão;

  • SQL é o oficial de operações;

  • Db2 é o computador central;

  • z/OS é a própria nave;

  • RACF é o chefe de segurança;

  • JES2 coordena os trabalhos;

  • CICS mantém a operação on-line;

  • e o programador é o tripulante tentando não causar um DELETE sem WHERE.


3. As cinco grandes famílias do SQL

Os comandos SQL costumam ser classificados em cinco grupos principais:

CategoriaSignificadoFinalidade
DDLData Definition LanguageCriar e alterar estruturas
DMLData Manipulation LanguageInserir, atualizar e excluir dados
DQLData Query LanguageConsultar dados
DCLData Control LanguageControlar permissões
TCLTransaction Control LanguageControlar transações

Essa divisão é didática.

Em alguns livros, o SELECT aparece dentro de DML. Em outros, é separado como DQL. Alguns produtos também apresentam variações de comportamento e sintaxe.

Não entre em guerra klingon por causa da classificação.

O mais importante é compreender a responsabilidade de cada comando.


4. DDL — Data Definition Language

DDL é a linguagem de definição de dados.

Ela cria e modifica a estrutura lógica dos objetos do banco.

Imagine que você esteja construindo uma nova nave da Frota Estelar.

Antes da tripulação embarcar, é necessário definir:

  • quantos decks existirão;

  • onde ficará a engenharia;

  • qual será a capacidade do reator;

  • onde serão instalados os escudos;

  • quantos alojamentos existirão;

  • como os corredores estarão conectados.

No banco, essa construção é feita com DDL.

Os comandos mais conhecidos são:

CREATE
ALTER
DROP
TRUNCATE
RENAME

4.1 CREATE — criando objetos

O CREATE cria novos objetos.

Exemplo:

CREATE TABLE CLIENTE
(
    ID_CLIENTE   INTEGER      NOT NULL,
    NOME         VARCHAR(100) NOT NULL,
    EMAIL        VARCHAR(150),
    DATA_CADASTRO DATE,
    SALDO        DECIMAL(11,2),
    PRIMARY KEY (ID_CLIENTE)
);

Aqui estamos criando uma tabela chamada CLIENTE.

Cada coluna possui um tipo:

  • INTEGER: número inteiro;

  • VARCHAR: texto de tamanho variável;

  • DATE: data;

  • DECIMAL: número decimal;

  • NOT NULL: a coluna não pode ficar vazia;

  • PRIMARY KEY: identifica cada registro de forma única.

O CREATE também pode criar:

CREATE INDEX
CREATE VIEW
CREATE SEQUENCE
CREATE DATABASE
CREATE TABLESPACE
CREATE PROCEDURE
CREATE TRIGGER

No Db2 for z/OS, o universo pode incluir objetos como:

  • database;

  • tablespace;

  • table;

  • index;

  • view;

  • alias;

  • synonym;

  • sequence;

  • stored procedure;

  • function;

  • package;

  • plan.

Nem todos são criados exatamente da mesma maneira em todos os bancos.

Essa é uma lição importante: SQL é padronizado, mas cada fabricante possui extensões e particularidades.


4.2 ALTER — reformando a nave durante a viagem

O ALTER modifica uma estrutura existente.

Por exemplo, imagine que a tabela CLIENTE já esteja em produção, mas agora a empresa deseja armazenar o telefone.

ALTER TABLE CLIENTE
ADD COLUMN TELEFONE VARCHAR(20);

Não foi necessário destruir a tabela.

Apenas adicionamos uma nova coluna.

Também podemos adicionar uma restrição:

ALTER TABLE CLIENTE
ADD CONSTRAINT CK_SALDO
CHECK (SALDO >= 0);

Ou aumentar o tamanho de uma coluna, dependendo do banco:

ALTER TABLE CLIENTE
ALTER COLUMN EMAIL
SET DATA TYPE VARCHAR(250);

Entretanto, o ALTER exige cuidado.

Modificar uma tabela vazia é simples.

Modificar uma tabela com:

  • 500 milhões de linhas;

  • dezenas de índices;

  • programas COBOL dependentes;

  • views;

  • triggers;

  • replicação;

  • rotinas de carga;

  • processos on-line;

é outra história.

Em ambientes mainframe, uma alteração estrutural pode exigir análise de impacto, regeneração de objetos, rebind de packages, testes de compatibilidade e planejamento de janela.

A pergunta não é apenas:

“O comando funciona?”

A pergunta madura é:

“Qual será o impacto dessa alteração em todo o ecossistema?”


4.3 DROP — autodestruição autorizada

O DROP remove um objeto.

DROP TABLE CLIENTE;

Esse comando pode remover:

  • a definição da tabela;

  • seus dados;

  • índices relacionados;

  • dependências, conforme o produto e as opções utilizadas.

É uma operação destrutiva.

Não confunda:

DELETE FROM CLIENTE;

com:

DROP TABLE CLIENTE;

O primeiro remove registros.

O segundo remove a própria tabela.

É como comparar:

  • retirar todos os tripulantes de uma nave;

  • explodir a nave inteira.

São situações completamente diferentes.

Em ambientes críticos, comandos DROP devem obedecer a controles rígidos, permissões específicas, aprovação de mudança e procedimentos de recuperação.


4.4 TRUNCATE — esvaziando o compartimento

O TRUNCATE remove todas as linhas de uma tabela, mas preserva sua estrutura.

TRUNCATE TABLE CLIENTE;

Após o comando:

  • a tabela continua existindo;

  • suas colunas continuam existindo;

  • os índices permanecem definidos;

  • as permissões normalmente permanecem;

  • os dados são removidos.

O TRUNCATE costuma ser mais rápido do que um DELETE sem WHERE, porque pode tratar a remoção em nível de páginas ou estruturas internas, evitando a mesma quantidade de trabalho linha por linha.

Mas isso varia conforme o SGBD.

Também é preciso verificar:

  • possibilidade de rollback;

  • comportamento do log;

  • restrições de integridade;

  • relacionamentos com outras tabelas;

  • triggers;

  • identidade;

  • opções específicas do produto.

A frase “TRUNCATE não pode ser desfeito” não é universal.

Em alguns bancos e contextos, pode haver comportamento transacional. Em outros, a operação possui restrições diferentes.

A regra de ouro é:

Nunca confie em uma frase genérica sobre banco de dados sem verificar o produto e a versão.


4.5 RENAME — mudando o nome da nave

O RENAME altera o nome de um objeto.

Exemplo genérico:

RENAME TABLE CLIENTE TO CLIENTES;

A sintaxe pode variar.

O cuidado está nas dependências.

Se você renomear uma tabela usada por:

  • programas COBOL;

  • jobs;

  • views;

  • stored procedures;

  • APIs;

  • relatórios;

  • scripts;

  • rotinas ETL;

todos esses consumidores poderão falhar.

Renomear não é apenas mudar uma etiqueta.

Em produção, pode significar alterar centenas de referências.


5. DML — Data Manipulation Language

DML é a linguagem de manipulação de dados.

Depois que a estrutura existe, precisamos inserir, alterar e remover registros.

Os comandos centrais são:

INSERT
UPDATE
DELETE
MERGE

5.1 INSERT — novos tripulantes a bordo

O INSERT adiciona registros.

INSERT INTO CLIENTE
(
    ID_CLIENTE,
    NOME,
    EMAIL,
    DATA_CADASTRO,
    SALDO
)
VALUES
(
    1001,
    'Vagner Bellacosa',
    'vagner@example.com',
    CURRENT_DATE,
    1500.00
);

É recomendável indicar explicitamente as colunas.

Evite depender da ordem física:

INSERT INTO CLIENTE
VALUES (1001, 'Vagner Bellacosa', ...);

Esse formato pode funcionar, mas é mais frágil.

Se a estrutura mudar, o comando pode quebrar ou inserir valores na posição errada.

Em sistemas reais, também podemos inserir dados a partir de outra consulta:

INSERT INTO CLIENTE_HISTORICO
SELECT *
FROM CLIENTE
WHERE DATA_CADASTRO < DATE('2020-01-01');

Esse padrão é usado em:

  • arquivamento;

  • migração;

  • cargas;

  • histórico;

  • preparação de ambientes de teste.


5.2 UPDATE — corrigindo a rota

O UPDATE altera registros existentes.

UPDATE CLIENTE
SET SALDO = SALDO + 500
WHERE ID_CLIENTE = 1001;

O maior perigo está na ausência do WHERE.

UPDATE CLIENTE
SET SALDO = 0;

Esse comando zera o saldo de todos os clientes.

Em uma tabela pequena de laboratório, isso vira aprendizado.

Em produção, vira reunião de crise, incidente, auditoria, relatório executivo e talvez uma visita nada amistosa do almirante.

Antes de executar um UPDATE, uma técnica valiosa é testar o filtro com SELECT:

SELECT *
FROM CLIENTE
WHERE ID_CLIENTE = 1001;

Somente depois:

UPDATE CLIENTE
SET SALDO = SALDO + 500
WHERE ID_CLIENTE = 1001;

Essa pequena disciplina evita grandes tragédias.


5.3 DELETE — removendo registros

O DELETE elimina linhas.

DELETE FROM CLIENTE
WHERE ID_CLIENTE = 1001;

Novamente, cuidado com o WHERE.

DELETE FROM CLIENTE;

Remove todas as linhas.

Ao contrário do DROP, a estrutura permanece.

Ao contrário do TRUNCATE, o DELETE pode trabalhar seletivamente:

DELETE FROM LOG_APLICACAO
WHERE DATA_EVENTO < CURRENT_DATE - 365 DAYS;

Essa exclusão remove apenas registros antigos.

Em grandes volumes, pode ser necessário apagar em lotes para evitar:

  • crescimento excessivo de log;

  • locks prolongados;

  • contenção;

  • impacto em concorrência;

  • grandes unidades de trabalho;

  • dificuldade de recuperação.


5.4 MERGE — o oficial multifunção

O MERGE combina decisões de atualização e inserção.

A lógica é:

  • se o registro já existe, atualize;

  • se não existe, insira.

Exemplo conceitual:

MERGE INTO CLIENTE C
USING CLIENTE_CARGA N
ON C.ID_CLIENTE = N.ID_CLIENTE

WHEN MATCHED THEN
    UPDATE SET
        C.NOME  = N.NOME,
        C.EMAIL = N.EMAIL

WHEN NOT MATCHED THEN
    INSERT
    (
        ID_CLIENTE,
        NOME,
        EMAIL
    )
    VALUES
    (
        N.ID_CLIENTE,
        N.NOME,
        N.EMAIL
    );

O MERGE é muito utilizado em:

  • ETL;

  • sincronização;

  • replicação;

  • Data Warehouse;

  • cargas incrementais;

  • integração entre sistemas;

  • atualização de cadastros.

Ele evita a necessidade de executar primeiro um SELECT, depois decidir entre INSERT ou UPDATE na aplicação.

Menos viagens entre programa e banco podem significar melhor desempenho e lógica mais centralizada.


6. DQL — Data Query Language

DQL é a linguagem de consulta de dados.

Seu grande representante é o SELECT.

SELECT NOME, SALDO
FROM CLIENTE;

Mas o universo do SELECT é gigantesco.

Ele pode:

  • filtrar;

  • ordenar;

  • agrupar;

  • calcular;

  • combinar tabelas;

  • numerar linhas;

  • comparar períodos;

  • executar subconsultas;

  • criar resultados analíticos;

  • produzir indicadores;

  • alimentar relatórios;

  • apoiar decisões.


6.1 WHERE — ativando os sensores

O WHERE filtra linhas.

SELECT *
FROM CLIENTE
WHERE SALDO > 1000;

Sem WHERE, todas as linhas são consideradas.

Com WHERE, selecionamos apenas o conjunto necessário.

Operadores comuns:

=
<>
>
<
>=
<=
BETWEEN
IN
LIKE
IS NULL
EXISTS

Exemplo:

SELECT NOME
FROM CLIENTE
WHERE ESTADO IN ('SP', 'RJ', 'MG');

6.2 ORDER BY — organizando a formação

SELECT NOME, SALDO
FROM CLIENTE
ORDER BY SALDO DESC;

DESC significa decrescente.

ASC significa crescente.

Sem ORDER BY, não se deve assumir uma ordem garantida.

Mesmo que o banco pareça devolver sempre igual, isso pode mudar conforme:

  • plano de acesso;

  • índice;

  • paralelismo;

  • reorganização;

  • estatísticas;

  • versão do banco.

Resultado sem ORDER BY é como uma formação de naves sem comandante: pode parecer organizada até o momento em que tudo muda.


6.3 GROUP BY — agrupando frotas

SELECT ESTADO, COUNT(*) AS QUANTIDADE
FROM CLIENTE
GROUP BY ESTADO;

O GROUP BY reúne linhas por uma característica.

Funções agregadas comuns:

COUNT
SUM
AVG
MIN
MAX

Exemplo:

SELECT ESTADO,
       COUNT(*) AS CLIENTES,
       SUM(SALDO) AS SALDO_TOTAL
FROM CLIENTE
GROUP BY ESTADO;

6.4 JOIN — conectando sistemas estelares

O JOIN combina dados de tabelas relacionadas.

SELECT C.NOME,
       P.NUMERO_PEDIDO,
       P.VALOR
FROM CLIENTE C
INNER JOIN PEDIDO P
    ON P.ID_CLIENTE = C.ID_CLIENTE;

Sem JOIN, as informações permaneceriam separadas.

Tipos comuns:

  • INNER JOIN;

  • LEFT JOIN;

  • RIGHT JOIN;

  • FULL JOIN;

  • CROSS JOIN.

O INNER JOIN retorna correspondências.

O LEFT JOIN preserva todas as linhas da tabela da esquerda.

Exemplo:

SELECT C.NOME,
       P.NUMERO_PEDIDO
FROM CLIENTE C
LEFT JOIN PEDIDO P
    ON P.ID_CLIENTE = C.ID_CLIENTE;

Mesmo clientes sem pedidos aparecerão.


7. DCL — Data Control Language

DCL controla permissões.

Os principais comandos são:

GRANT
REVOKE

Em uma nave, nem todo tripulante pode:

  • acessar o reator;

  • disparar torpedos;

  • alterar o computador central;

  • consultar arquivos secretos;

  • iniciar a autodestruição.

No banco, também não deveria ser assim.


7.1 GRANT — concedendo autorização

GRANT SELECT
ON TABLE CLIENTE
TO USER ANALISTA01;

O usuário recebe autorização para consultar a tabela.

Também podemos conceder permissões como:

SELECT
INSERT
UPDATE
DELETE
ALTER
CONTROL
EXECUTE

O conjunto exato depende do produto.

Uma boa prática de segurança é o princípio do menor privilégio:

Conceda apenas o acesso necessário para executar a função.

Um analista que apenas consulta relatórios não precisa de permissão para apagar tabelas.


7.2 REVOKE — retirando autorização

REVOKE SELECT
ON TABLE CLIENTE
FROM USER ANALISTA01;

O acesso é removido.

Isso é importante quando:

  • alguém muda de função;

  • um contrato termina;

  • um usuário deixa a empresa;

  • uma aplicação é desativada;

  • uma permissão foi concedida indevidamente;

  • uma auditoria identifica excesso de privilégio.

No Db2 for z/OS, o controle de acesso pode envolver a interação entre autorizações do Db2 e mecanismos externos de segurança, como RACF, dependendo da arquitetura adotada.

Segurança de banco não deve ser tratada como um detalhe colocado no final do projeto.

Ela precisa nascer junto com a solução.


8. TCL — Transaction Control Language

TCL controla transações.

Os comandos mais conhecidos são:

COMMIT
ROLLBACK
SAVEPOINT

Esta é uma das partes mais importantes para quem desenvolve sistemas corporativos.


9. O que é uma transação?

Uma transação é uma unidade lógica de trabalho.

Imagine uma transferência bancária:

  1. retirar R$ 500 da conta A;

  2. adicionar R$ 500 à conta B;

  3. registrar o movimento;

  4. confirmar a operação.

Não podemos permitir que apenas metade aconteça.

Se o valor sair da conta A, mas não entrar na conta B, o sistema ficará inconsistente.

A transação deve ser tratada como um conjunto indivisível.

Ou tudo funciona.

Ou tudo é desfeito.


9.1 COMMIT — missão confirmada

O COMMIT confirma as alterações.

UPDATE CONTA
SET SALDO = SALDO - 500
WHERE NUMERO = 100;

UPDATE CONTA
SET SALDO = SALDO + 500
WHERE NUMERO = 200;

COMMIT;

Depois do COMMIT, a unidade de trabalho é concluída.

No Db2, o COMMIT também possui impacto em:

  • locks;

  • log;

  • concorrência;

  • recuperação;

  • cursores;

  • duração da unidade de trabalho.

Executar commits com pouca frequência pode criar transações gigantescas.

Executar commits a cada linha pode causar sobrecarga e comprometer a lógica da aplicação.

É necessário equilíbrio.


9.2 ROLLBACK — abortar missão

Se algo falhar:

ROLLBACK;

As alterações da unidade de trabalho são desfeitas.

Exemplo:

UPDATE CONTA
SET SALDO = SALDO - 500
WHERE NUMERO = 100;

-- Falha ao atualizar a conta de destino

ROLLBACK;

O saldo da conta de origem volta ao estado anterior.

O ROLLBACK é o botão de emergência.


9.3 SAVEPOINT — ponto de restauração

O SAVEPOINT cria um marco dentro da transação.

SAVEPOINT ETAPA_1 ON ROLLBACK RETAIN CURSORS;

A sintaxe varia conforme o banco.

Depois, pode ser possível retornar ao ponto:

ROLLBACK TO SAVEPOINT ETAPA_1;

Isso permite desfazer apenas parte do trabalho.

Imagine uma missão com cinco etapas.

Após a terceira, você cria um checkpoint.

Se a quinta falhar, pode voltar à terceira, em vez de reiniciar tudo.


10. As propriedades ACID

Transações confiáveis são frequentemente explicadas pelo acrônimo ACID.

Atomicidade

Ou tudo acontece, ou nada acontece.

A transferência bancária não pode ficar pela metade.

Consistência

A transação leva o banco de um estado válido para outro estado válido.

Regras e constraints devem ser preservadas.

Isolamento

Transações simultâneas não devem interferir de maneira incorreta umas nas outras.

Durabilidade

Após o COMMIT, os dados devem sobreviver a falhas.

ACID é uma das razões pelas quais bancos relacionais permanecem essenciais em sistemas financeiros, governamentais, industriais e corporativos.


11. DELETE, TRUNCATE e DROP: o trio das entrevistas

Essa comparação aparece constantemente.

DELETE

Remove linhas.

DELETE FROM CLIENTE
WHERE ESTADO = 'SP';
  • aceita WHERE;

  • pode remover algumas ou todas as linhas;

  • a tabela permanece;

  • normalmente participa de transações;

  • pode gerar trabalho de log linha a linha.

TRUNCATE

Esvazia a tabela.

TRUNCATE TABLE CLIENTE;
  • remove todas as linhas;

  • não usa WHERE;

  • preserva a estrutura;

  • costuma ser mais rápido;

  • possui particularidades conforme o banco.

DROP

Remove o objeto.

DROP TABLE CLIENTE;
  • remove estrutura;

  • remove dados;

  • pode afetar dependências;

  • exige extremo cuidado.

Resumo Bellacosa:

DELETE   = desembarcar alguns ou todos os tripulantes
TRUNCATE = esvaziar completamente a nave
DROP     = desmontar a nave no estaleiro

12. SQL dentro de um programa COBOL

No mundo mainframe, SQL pode aparecer embutido no COBOL.

Exemplo:

       EXEC SQL
           SELECT NOME,
                  SALDO
             INTO :WS-NOME,
                  :WS-SALDO
             FROM CLIENTE
            WHERE ID_CLIENTE = :WS-ID-CLIENTE
       END-EXEC.

As variáveis precedidas por : são host variables.

Elas fazem a ponte entre COBOL e SQL.

Após a execução, o programa deve verificar o SQLCODE ou SQLSTATE.

Exemplo:

       EVALUATE SQLCODE
           WHEN 0
               DISPLAY 'CLIENTE ENCONTRADO'
           WHEN 100
               DISPLAY 'CLIENTE NAO ENCONTRADO'
           WHEN OTHER
               DISPLAY 'ERRO SQL: ' SQLCODE
       END-EVALUATE.

Em muitos ambientes Db2:

  • SQLCODE = 0: sucesso;

  • SQLCODE = +100: nenhuma linha encontrada ou fim do cursor;

  • valor negativo: erro;

  • valor positivo diferente de 100: aviso ou condição específica.

Nunca ignore o SQLCODE.

Ignorar o retorno do banco é como ignorar um alerta vermelho na ponte porque o café ainda está quente.


13. Cursores em COBOL e Db2

Quando um SELECT retorna várias linhas, usamos cursor.

Fluxo tradicional:

  1. DECLARE CURSOR;

  2. OPEN;

  3. FETCH;

  4. repetir até SQLCODE +100;

  5. CLOSE.

Exemplo simplificado:

       EXEC SQL
           DECLARE C1 CURSOR FOR
           SELECT ID_CLIENTE,
                  NOME
             FROM CLIENTE
            ORDER BY ID_CLIENTE
       END-EXEC.

       EXEC SQL
           OPEN C1
       END-EXEC.

       PERFORM UNTIL SQLCODE = +100

           EXEC SQL
               FETCH C1
                INTO :WS-ID-CLIENTE,
                     :WS-NOME
           END-EXEC

           IF SQLCODE = 0
               DISPLAY WS-ID-CLIENTE ' ' WS-NOME
           END-IF

       END-PERFORM.

       EXEC SQL
           CLOSE C1
       END-EXEC.

O programador precisa entender o impacto do COMMIT sobre cursores.

Dependendo de como o cursor foi declarado, um COMMIT pode fechá-lo.

Uma opção conhecida é:

WITH HOLD

Exemplo:

DECLARE C1 CURSOR WITH HOLD FOR
SELECT ...

Isso pode preservar o cursor através de commits, respeitando as regras do Db2.


14. Cuidados com COMMIT em processamento batch

Imagine um programa COBOL que atualiza 10 milhões de registros.

Fazer um único COMMIT no final pode resultar em:

  • unidade de trabalho enorme;

  • crescimento de log;

  • locks prolongados;

  • dificuldade de restart;

  • grande rollback em caso de erro;

  • impacto em outros processos.

Por outro lado, fazer COMMIT a cada registro pode:

  • aumentar o custo;

  • reduzir desempenho;

  • dificultar consistência;

  • gerar excesso de pontos de sincronização.

Uma estratégia comum é confirmar em lotes:

a cada 1.000 registros
a cada 5.000 registros
a cada 10.000 registros

O número ideal depende de:

  • volume;

  • tempo de execução;

  • tamanho das linhas;

  • concorrência;

  • capacidade de log;

  • estratégia de restart;

  • requisitos de negócio;

  • janela batch.

Não existe um número mágico universal.

O profissional experiente mede, testa e conversa com DBA, produção e arquitetura.


15. Passo a passo para praticar SQL

Vamos montar uma pequena estação de treinamento.

Passo 1 — criar a tabela

CREATE TABLE TRIPULANTE
(
    ID_TRIPULANTE INTEGER NOT NULL,
    NOME          VARCHAR(100) NOT NULL,
    POSTO         VARCHAR(50),
    NAVE          VARCHAR(50),
    CREDITOS      DECIMAL(10,2),
    PRIMARY KEY (ID_TRIPULANTE)
);

Passo 2 — inserir registros

INSERT INTO TRIPULANTE
VALUES
(1, 'James Kirk', 'Capitao', 'Enterprise', 5000.00);

INSERT INTO TRIPULANTE
VALUES
(2, 'Spock', 'Oficial de Ciencia', 'Enterprise', 4800.00);

INSERT INTO TRIPULANTE
VALUES
(3, 'Montgomery Scott', 'Engenheiro Chefe', 'Enterprise', 4500.00);

Passo 3 — consultar

SELECT *
FROM TRIPULANTE;

Passo 4 — filtrar

SELECT NOME, POSTO
FROM TRIPULANTE
WHERE CREDITOS > 4600;

Passo 5 — atualizar

UPDATE TRIPULANTE
SET CREDITOS = CREDITOS + 500
WHERE ID_TRIPULANTE = 3;

Passo 6 — confirmar

COMMIT;

Passo 7 — testar rollback

UPDATE TRIPULANTE
SET CREDITOS = 0;

ROLLBACK;

Após o rollback, os créditos devem retornar ao estado anterior.

Passo 8 — adicionar coluna

ALTER TABLE TRIPULANTE
ADD COLUMN PLANETA_ORIGEM VARCHAR(50);

Passo 9 — conceder acesso

GRANT SELECT
ON TABLE TRIPULANTE
TO USER CADETE01;

Passo 10 — remover um registro

DELETE FROM TRIPULANTE
WHERE ID_TRIPULANTE = 3;

Esse laboratório apresenta praticamente todas as categorias principais.


16. Erros clássicos do SQL Padawan

Executar UPDATE sem WHERE

UPDATE FUNCIONARIO
SET SALARIO = 1000;

Todos os salários serão alterados.

Executar DELETE sem WHERE

DELETE FROM FUNCIONARIO;

Todos os registros serão removidos.

Usar SELECT *

SELECT *
FROM CLIENTE;

É útil para testes, mas em programas e consultas profissionais pode trazer colunas desnecessárias, aumentar tráfego e criar dependências frágeis.

Prefira:

SELECT ID_CLIENTE,
       NOME,
       EMAIL
FROM CLIENTE;

Não tratar NULL

NULL não é zero.

NULL não é espaço.

NULL significa ausência de valor conhecido.

Isto está errado:

WHERE EMAIL = NULL

O correto é:

WHERE EMAIL IS NULL

Ignorar transações

Atualizar tabelas relacionadas sem pensar em COMMIT e ROLLBACK é um convite à inconsistência.

Ignorar o plano de acesso

Uma consulta correta pode ser lenta.

É preciso compreender:

  • índices;

  • estatísticas;

  • cardinalidade;

  • joins;

  • filtros;

  • ordenações;

  • acesso por tabela ou índice;

  • custo estimado.

No Db2, EXPLAIN é uma ferramenta essencial nessa jornada.


17. Curiosidades do universo SQL

SQL já foi chamado de SEQUEL

A linguagem desenvolvida inicialmente na IBM era associada ao nome SEQUEL, de Structured English Query Language.

Por razões relacionadas a marca, o nome foi encurtado para SQL.

Por isso algumas pessoas pronunciam:

“és-quê-éle”

e outras:

“síquel”.

Ambas as formas aparecem no mercado.

SQL é declarativo

Você descreve o resultado, não necessariamente o caminho.

SELECT NOME
FROM CLIENTE
WHERE ID_CLIENTE = 100;

Você não manda o banco:

  • abrir o índice;

  • ir à página;

  • localizar a linha;

  • carregar a coluna.

O otimizador decide o plano.

SELECT pode não pertencer à DQL em todas as classificações

Algumas referências tratam SELECT como parte da DML.

A classificação DQL é muito usada em materiais didáticos, mas não representa uma verdade absoluta e universal.

Nem todo comando existe igualmente em todo banco

A sintaxe e o comportamento variam entre:

  • Db2;

  • Oracle;

  • PostgreSQL;

  • SQL Server;

  • MySQL;

  • MariaDB;

  • SQLite.

Aprenda o conceito e depois confirme a implementação.


18. Como entrevistas cobram esses conhecimentos

O entrevistador raramente quer apenas ouvir a lista:

DDL, DML, DQL, DCL e TCL.

Ele quer perceber se você entende situações reais.

Perguntas possíveis:

Qual a diferença entre DELETE, TRUNCATE e DROP?

Responda considerando:

  • linhas;

  • estrutura;

  • filtro;

  • log;

  • transação;

  • desempenho;

  • impacto.

O que acontece se um UPDATE não tiver WHERE?

Todas as linhas elegíveis serão atualizadas.

Por que não fazer um único COMMIT em um batch gigantesco?

Pode gerar unidade de trabalho extensa, locks, log elevado, rollback demorado e dificuldade de restart.

Quando usar MERGE?

Quando é necessário inserir registros inexistentes e atualizar os já existentes com base em uma condição.

Qual a função do GRANT?

Conceder privilégios sobre objetos ou operações.

O que significa SQLCODE +100?

Em muitos cenários Db2, indica que nenhuma linha foi encontrada ou que o cursor chegou ao final.

Por que um índice pode melhorar o SELECT e prejudicar o INSERT?

O índice acelera algumas buscas, mas precisa ser mantido a cada inserção, atualização ou exclusão.

Essa última pergunta já mostra que banco de dados é uma disciplina de equilíbrio.


19. O caminho depois dos comandos básicos

Após dominar as famílias SQL, avance para:

  1. filtros e operadores;

  2. funções escalares;

  3. agregações;

  4. joins;

  5. subqueries;

  6. CTEs;

  7. window functions;

  8. views;

  9. constraints;

  10. índices;

  11. transações;

  12. níveis de isolamento;

  13. locking;

  14. deadlocks;

  15. EXPLAIN;

  16. otimização;

  17. stored procedures;

  18. triggers;

  19. particionamento;

  20. segurança e auditoria.

Não tente aprender tudo em um único warp.

A evolução acontece em camadas.

Primeiro, compreenda o que cada comando faz.

Depois, entenda quando deve ser usado.

Em seguida, estude o impacto.

Finalmente, aprenda a operar em escala.


20. Easter egg: o protocolo Kobayashi Maru do SQL

Existe um teste não oficial que todo programador enfrenta em algum momento.

Você está conectado em uma base.

Recebe a tarefa:

“Corrigir apenas um registro.”

Digita:

UPDATE CLIENTE
SET STATUS = 'INATIVO';

E percebe, um segundo depois, que esqueceu o WHERE.

Este é o Kobayashi Maru do SQL.

A diferença é que, neste teste, existe uma chance de sobrevivência:

  • não faça COMMIT;

  • execute ROLLBACK;

  • respire;

  • valide os dados;

  • revise o processo;

  • nunca mais atualize antes de testar o filtro com SELECT.

Kirk trapaceou no Kobayashi Maru.

O programador SQL aprende a usar transações.


Conclusão — Da primeira consulta ao comando da ponte

SQL não é apenas uma coleção de comandos.

É uma forma estruturada de pensar sobre dados.

DDL constrói o universo.

DML movimenta seus habitantes.

DQL observa e interpreta.

DCL protege as fronteiras.

TCL mantém a linha temporal consistente.

Para o programador COBOL, dominar essas categorias significa compreender melhor como as aplicações corporativas realmente funcionam.

Um programa não vive sozinho.

Ele depende de tabelas, índices, permissões, locks, transações, logs, packages, planos de acesso, unidades de trabalho e mecanismos de recuperação.

O iniciante memoriza:

SELECT
INSERT
UPDATE
DELETE

O profissional pergunta:

  • Quantas linhas serão afetadas?

  • Existe índice adequado?

  • O filtro está correto?

  • Qual será o nível de isolamento?

  • Quando ocorrerá o COMMIT?

  • Como o processo será reiniciado?

  • O usuário possui autorização?

  • Qual será o impacto sobre outros sistemas?

  • O programa está tratando o SQLCODE?

  • Existe uma estratégia de rollback?

Essa é a diferença entre escrever SQL e entender SQL.

Comece com uma tabela pequena.

Faça inserts.

Teste updates.

Use rollback.

Crie uma coluna.

Conceda uma permissão.

Abra um cursor em COBOL.

Observe o SQLCODE.

Depois repita.

O conhecimento não vem de decorar uma imagem com cinco caixas coloridas. Ele nasce quando você executa, erra em laboratório, investiga o comportamento e compreende por que cada comando existe.

E lembre-se, Padawan:

Um SELECT mostra o que existe.
Um INSERT cria um novo registro.
Um UPDATE muda a realidade.
Um DELETE apaga evidências.
Um COMMIT sela a linha do tempo.

Portanto, antes de pressionar Enter, confira o WHERE.

A Frota Estelar agradece. 

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