Translate

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. 

Sem comentários:

Enviar um comentário