Oracle DB · PL/SQL · Migracao para SQL Server · Performance · ETL

Oracle Database & PL/SQL – Desenvolvimento, Migracao e Tuning de Performance

Eu desenvolvo, otimizo e migro solucoes Oracle de banco de dados da versao 8i ate 19c. O escopo abrange desde packages PL/SQL com cursors complexos, mecanismos de bulk collect e tratamento estruturado de excecoes, passando por analise de performance com explain plans e hints de otimizador, ate migracoes completas para SQL Server usando SSMA, mapeamento de tipos de dados e conversao de PL/SQL para T-SQL. Como freelancer com experiencia desde 1994, trago a profundidade tecnica que grandes ambientes Oracle demandam — tanto no desenvolvimento continuo quanto em projetos desafiadores de migracao.

Posicionamento

Oracle e o banco de dados central de muitas organizacoes que executam aplicacoes de missao critica. Ao mesmo tempo, Oracle e uma das plataformas de banco de dados mais complexas do mercado: o modelo de instancia com SGA, PGA e processos de background, a linguagem PL/SQL com suas proprias convencoes, as sutilezas do comportamento do otimizador e a complexidade particular dos projetos de migracao fazem da expertise Oracle um campo especializado. Eu trabalho com bancos de dados Oracle desde o inicio dos anos 2000 — do Oracle 8i passando por 10g, 11g, 12c e 18c ate a atual geracao 19c. Essa amplitude me permite entender sistemas legados e ao mesmo tempo usar recursos modernos do Oracle de forma direcionada.

O que distingue meu trabalho com Oracle e a combinacao de profundidade no desenvolvimento PL/SQL com um historico abrangente em projetos de migracao. Muitos clientes chegam a mim quando um sistema Oracle legado precisa ser substituido: aplicacoes Java com backend Oracle que precisam migrar para .NET e SQL Server, ou processos ETL Oracle que precisam ser substituidos por pipelines SSIS modernos. Eu conheo ambos os lados — o sistema Oracle de origem e a plataforma SQL Server de destino — e posso conduzir projetos de migracao sem a habitual transferencia de conhecimento entre dois especialistas distintos.

Alem disso, tenho experiencia em tuning de performance Oracle. Um package PL/SQL mal otimizado ou uma consulta sem indice adequado pode sobrecarregar seriamente um banco de dados Oracle. Analise de explain plan, uso de hints de otimizador, uso correto de bind variables e projeto de indices sao ferramentas que aplico sistematicamente ao diagnosticar e resolver problemas de performance de forma sustentavel. Essa combinacao de competencias em desenvolvimento, migracao e performance e o valor que trago a projetos Oracle.

Perfil central Oracle: Desenvolvimento PL/SQL, tuning de performance e migracao para SQL Server formam meus tres pilares no espaco Oracle. Trago a profundidade que grandes instalacoes Oracle exigem e a experiencia em migracao que permite que projetos de substituicao avancem sem perda de informacao.

Oracle 8i a 19c

Os bancos de dados Oracle evoluiram ao longo de varias decadas para um ecossistema complexo. A versao 8i trouxe integracao com internet; 9i melhorou os Real Application Clusters; 10g introduziu computacao em grade e gerenciamento automatico de segmentos (ASSM); 11g fortaleceu as capacidades de Data Guard e RAC; 12c introduziu a arquitetura multitenant com CDB e PDB; 18c e 19c consolidaram a geracao de suporte de longo prazo do Oracle moderno. Cada versao trouxe novos recursos PL/SQL, novas tecnologias de otimizador e novas ferramentas de administracao. Essa amplitude de versoes tem grande relevancia pratica em ambientes legados: muitas instalacoes ainda rodam Oracle 11g ou 12c, e o codigo que funciona la se baseia em comportamentos diferentes do codigo atual 19c.

Edicoes Oracle e Implicacoes de Licenciamento

Oracle esta disponivel em varias edicoes: Oracle Database Express Edition (XE) para ambientes pequenos e desenvolvimento; Standard Edition 2 (SE2) para ambientes de producao menores; e Enterprise Edition (EE) para o conjunto completo de recursos. O modelo de licenciamento Oracle — em especial o licenciamento por processador da Enterprise Edition — e um fator principal em projetos de migracao. Quando uma empresa substitui Oracle EE por SQL Server Standard ou Enterprise, os custos de licenca podem ser significativamente reduzidos. Considero sempre essa dimensao de licenciamento nas decisoes de migracao, pois frequentemente e a razao principal pela qual um projeto e iniciado.

Cargas de Trabalho Tipicas Oracle

No trabalho diario de projetos, encontro bancos de dados Oracle em tres papeis tipicos: como backend para aplicacoes Java com acesso JDBC; como banco de dados fonte de ETL — geralmente junto com ODI, Informatica ou PL/SQL proprio; e como banco de dados central para sistemas de faturamento e seguros com extensa logica de stored procedures. Esses papeis exigem enfases diferentes: aplicacoes com uso intenso de JDBC tipicamente sofrem com falta de bind variables e overhead de parse; ambientes ETL se beneficiam mais de otimizacoes de bulk collect; sistemas de faturamento requerem tratamento robusto de excecoes e packages PL/SQL transacionalmente seguros.

  • Oracle 8i a 19c: amplitude de versoes de projetos reais
  • Arquitetura multitenant: CDB e PDB desde Oracle 12c
  • Edicoes: XE, SE2, EE — consideracoes de licenciamento em migracoes
  • Real Application Clusters (RAC): entendimento fundamental e escopo
  • Recursos Oracle: particionamento, materialized views, advanced queuing
  • Desenvolvimento PL/SQL: packages, procedimentos, funcoes, triggers
  • Tooling: SQL*Plus (automacao de scripts), SQL Developer, TOAD
  • Performance: otimizador, explain plan, hints, indices
  • Migracao: SSMA, mapeamento de tipos, PL/SQL para T-SQL
O conhecimento de versoes Oracle nao e um fim em si mesmo. Ele determina se voce faz as perguntas certas no contexto de uma migracao legada: quais recursos existem na versao de origem que devem ser mapeados no sistema de destino? Onde ha diferencas sintaticas a observar? Conhecer a plataforma de origem permite migracoes mais seguras.

Arquitetura de Banco de Dados e Modelo de Instancia

O modelo de instancia Oracle e fundamentalmente diferente do SQL Server. Uma instancia Oracle consiste em estruturas de memoria (SGA — System Global Area) e um conjunto de processos de background; os arquivos de banco de dados residem separadamente. Essa separacao de instancia e banco de dados tem consequencias de longo alcance: e possivel iniciar uma instancia sem montar um banco de dados; um banco de dados pode ser conectado a uma instancia diferente. Esse modelo e a base para Oracle RAC, Data Guard e Multitenant. Qualquer pessoa administrando ou migrando Oracle precisa ter internalizado esse modelo.

Arquitetura Oracle Database: SGA com shared pool, buffer cache e redo log buffer, processos de background DBWn, LGWR, CKPT, SMON, PMON e camada de armazenamento fisico

Esquema da instancia Oracle: a SGA mantem estruturas de memoria compartilhadas para todas as sessoes; processos de background coordenam operacoes de escrita, log e recuperacao; arquivos de dados, redo logs e o arquivo de controle formam a camada de armazenamento persistente.

SGA: Shared Pool, Buffer Cache e Redo Log Buffer

O shared pool armazena instrucoes SQL analisadas e unidades PL/SQL compiladas na library cache, e metadados do banco de dados no data dictionary cache. Codigo mal otimizado que usa valores literais em vez de bind variables forca o Oracle a analisar a mesma instrucao repetidamente — um problema classico de performance que pressiona o shared pool e gera overhead de hard parse. O buffer cache mantem blocos de dados na memoria para minimizar leituras fisicas dos arquivos de dados. A taxa de acerto do buffer cache e um indicador precoce de escassez de memoria quando cai abaixo de limiares tipicos. O redo log buffer enfileira registros de mudanca antes que o processo LGWR os grave nos arquivos de redo log.

Processos de Background: DBWn, LGWR, CKPT, SMON, PMON

Os processos de background sao a espinha dorsal da instancia Oracle. DBWn (Database Writer) grava blocos de dados modificados do buffer cache nos arquivos de dados — de forma assincrona e no seu proprio ritmo, nao imediatamente apos cada COMMIT. LGWR (Log Writer) grava o redo log buffer nos arquivos de redo log em cada COMMIT, garantindo a durabilidade das transacoes. CKPT (Checkpoint) registra o SCN ate o qual todas as mudancas foram gravadas em disco — um checkpoint minimiza o tempo de recuperacao. SMON (System Monitor) realiza recuperacao de falhas e limpa segmentos temporarios. PMON (Process Monitor) limpa apos conexoes com falha. Entender como esses processos interagem e essencial para diagnosticar problemas de performance e para compreender como o Oracle processa transacoes internamente.

Multitenant: CDB e PDB desde Oracle 12c

Oracle 12c introduziu a arquitetura multitenant: um Container Database (CDB) pode hospedar varios Pluggable Databases (PDB). Cada PDB tem seus proprios dados, seu proprio esquema e sua propria configuracao, mas compartilha recursos de instancia (SGA, processos de background) com outros PDBs. Essa arquitetura e o equivalente Oracle de uma instancia SQL Server com varios bancos de dados, mas com particularidades proprias em strings de conexao, modelos de autorizacao e tratamento de usuarios comuns. Em migracoes de ambientes 12c/19c, e importante saber se o codigo executa no nivel CDB ou PDB.

O modelo de instancia Oracle explica muitos fenomenos de performance que de outra forma pareceriam misteriosos: por que um COMMIT as vezes trava? Por causa de tempos de espera do LGWR. Por que uma consulta fica mais lenta apos um hard parse? Por causa de invalidacao de cache no shared pool. Entender a arquitetura possibilita diagnosticos mais direcionados.

PL/SQL: Packages, Procedimentos, Cursors

PL/SQL e a extensao procedural SQL da Oracle. Diferentemente do T-SQL, que executa diretamente no contexto do SQL Server, o PL/SQL tem sua propria infraestrutura de compilador, seus proprios conceitos de memoria e sua propria semantica para transacoes e bloqueios. O construto mais poderoso no PL/SQL e o package: uma unidade que agrupa definicoes de tipo, variaveis, procedimentos e funcoes, e fornece uma separacao clara entre a interface publica (specification) e a implementacao (body). Packages podem manter estado durante toda uma sessao — uma capacidade que o SQL Server nao tem diretamente e que requer atencao cuidadosa em migracoes.

Estrutura de package PL/SQL com specification e body, logica de cursor, tratador de excecoes e acesso ao banco de dados

Diagrama de estrutura de um package PL/SQL: a specification define a interface publica com assinaturas de procedimentos, definicoes de tipo e declaracoes de REF CURSOR. O body implementa a logica com cursors, etapas de bulk collect e tratamento estruturado de excecoes.

Package Specification e Body

A specification de um package PL/SQL equivale a um cabecalho em C ou uma interface em Java: ela declara o que e visivel externamente. Isso inclui assinaturas de procedimentos e funcoes, definicoes de tipo (TYPE ... IS TABLE OF, TYPE ... IS RECORD), constantes e variaveis publicas. O body contem a implementacao real de tudo que foi declarado na specification, mais procedimentos auxiliares privados que nao sao acessiveis externamente. Essa modularizacao e indispensavel para sistemas maiores: permite que a interface permaneca estavel enquanto o body evolui independentemente. Eu uso packages de forma consistente porque tornam o codigo mais testavel, mantivel e documentavel.

Cursors Explicitos e Ref Cursors

Um cursor explicito da ao desenvolvedor controle total sobre o processo de consulta: OPEN, FETCH (linha por linha ou em bulk) e CLOSE. Esse controle e necessario quando o processamento deve ser linha a linha ou quando o cursor e usado em varios lugares no codigo. O ref cursor (REF CURSOR ou SYS_REFCURSOR) e um ponteiro para um conjunto de resultados de cursor, que pode ser passado como parametro ou retornado ao chamador. Ref cursors sao o padrao para procedimentos que retornam conjuntos de resultados a camadas chamadoras — comparavel a um recordset em ADO ou um DataReader em ADO.NET. Em migracoes para SQL Server, procedimentos com ref cursor sao tipicamente convertidos em stored procedures que retornam um conjunto de resultados SELECT.

PL/SQL · Package com cursor, ref cursor e tratamento de excecoes
-- Especificacao do package: interface publica
CREATE OR REPLACE PACKAGE pkg_pedidos AS
    -- Tipo publico para operacoes de bulk collect
    TYPE t_pedidos_tab IS TABLE OF pedidos%ROWTYPE;

    -- Tipo de ref cursor para retorno de conjuntos de resultados
    TYPE t_ref_cursor IS REF CURSOR;

    -- Procedimento: processa pedidos de um cliente
    PROCEDURE processar_pedidos(
        p_cliente_id  IN  pedidos.cliente_id%TYPE,
        p_status      IN  VARCHAR2 DEFAULT 'ABERTO',
        p_resultado   OUT t_ref_cursor,
        p_quantidade  OUT NUMBER
    );

    -- Funcao: valor total de um cliente
    FUNCTION get_valor_total(
        p_cliente_id IN pedidos.cliente_id%TYPE
    ) RETURN NUMBER;
END pkg_pedidos;
/

-- Body do package: implementacao
CREATE OR REPLACE PACKAGE BODY pkg_pedidos AS

    -- Procedimento auxiliar privado (somente uso interno)
    PROCEDURE registrar_erro(p_codigo IN NUMBER, p_mensagem IN VARCHAR2) IS
        PRAGMA AUTONOMOUS_TRANSACTION;  -- transacao independente para log
    BEGIN
        INSERT INTO log_erros (codigo_erro, mensagem_erro, criado_em)
        VALUES (p_codigo, p_mensagem, SYSDATE);
        COMMIT;  -- commit somente para a transacao autonoma
    END registrar_erro;

    -- Procedimento principal com cursor explicito e bulk collect
    PROCEDURE processar_pedidos(
        p_cliente_id  IN  pedidos.cliente_id%TYPE,
        p_status      IN  VARCHAR2 DEFAULT 'ABERTO',
        p_resultado   OUT t_ref_cursor,
        p_quantidade  OUT NUMBER
    ) IS
        -- Colecao local para processamento em bulk
        v_pedidos   t_pedidos_tab;

        -- Cursor explicito: selecao de dados
        CURSOR c_pedidos IS
            SELECT * FROM pedidos
            WHERE  cliente_id = p_cliente_id
            AND    status     = p_status
            ORDER BY criado_em;
    BEGIN
        -- Bulk collect: carrega o resultado inteiro em uma colecao
        OPEN c_pedidos;
        FETCH c_pedidos BULK COLLECT INTO v_pedidos LIMIT 1000;
        CLOSE c_pedidos;

        p_quantidade := v_pedidos.COUNT;

        -- Processamento linha a linha dentro da colecao
        FOR i IN 1 .. v_pedidos.COUNT LOOP
            UPDATE pedidos
            SET    processado_em = SYSDATE,
                   processado_por = USER
            WHERE  pedido_id = v_pedidos(i).pedido_id;
        END LOOP;

        -- Abre o ref cursor de resultado para o chamador
        OPEN p_resultado FOR
            SELECT * FROM pedidos
            WHERE  cliente_id = p_cliente_id
            AND    status     = p_status
            ORDER BY criado_em;

    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            p_quantidade := 0;
            -- Nenhum erro propagado; retorna cursor vazio
            OPEN p_resultado FOR SELECT * FROM pedidos WHERE 1=0;
        WHEN OTHERS THEN
            -- Registra todos os erros nao tratados
            registrar_erro(SQLCODE, SQLERRM);
            RAISE;  -- propaga ao chamador
    END processar_pedidos;

    FUNCTION get_valor_total(
        p_cliente_id IN pedidos.cliente_id%TYPE
    ) RETURN NUMBER IS
        v_total NUMBER := 0;
    BEGIN
        SELECT NVL(SUM(valor), 0)
        INTO   v_total
        FROM   pedidos
        WHERE  cliente_id = p_cliente_id;
        RETURN v_total;
    EXCEPTION
        WHEN OTHERS THEN
            registrar_erro(SQLCODE, SQLERRM);
            RETURN NULL;
    END get_valor_total;

END pkg_pedidos;
/

Este package demonstra o padrao completo: specification com tipos publicos e assinaturas; body com auxiliar privado usando PRAGMA AUTONOMOUS_TRANSACTION; cursor explicito; bulk collect; e retorno via ref cursor. Comentarios em portugues, apenas caracteres ASCII.

Packages PL/SQL sao a espinha dorsal de aplicacoes Oracle bem estruturadas. A separacao entre specification e body, o encapsulamento de auxiliares privados e o uso de estado em nivel de package sao capacidades que o T-SQL nao possui diretamente — e que devem ser cuidadosamente mapeadas em migracoes.

Bulk Collect, Bulk Bind e Pipelined Functions

Uma das armadilhas de performance mais comuns no PL/SQL e a abordagem linha por linha: um loop abre um cursor, le uma linha, a processa, emite um UPDATE — e repete isso para milhares ou milhoes de linhas. Cada troca entre a engine PL/SQL e a engine SQL custa tempo; com muitas iteracoes, esse overhead de troca de contexto se acumula significativamente. Bulk Collect e Bulk Bind resolvem esse problema lendo ou gravando multiplas linhas em uma unica chamada da engine SQL.

BULK COLLECT INTO com LIMIT

FETCH ... BULK COLLECT INTO carrega multiplas linhas de uma vez em uma colecao PL/SQL (VARRAY, nested table ou array associativo). A clausula LIMIT opcional limita o tamanho de cada carga e impede que o resultado inteiro do cursor seja carregado sem controle na memoria PGA. Para volumes grandes de dados, um LIMIT de 500 a 2000 linhas e tipicamente otimo: grande o suficiente para minimizar o overhead de troca de contexto, pequeno o suficiente para evitar overflow da PGA.

FORALL: Bulk DML

O comando FORALL e o complemento do BULK COLLECT no lado DML: executa um INSERT, UPDATE ou DELETE para todos os elementos de uma colecao em uma unica chamada da engine SQL. Diferentemente de um loop FOR com DML, FORALL reduz drasticamente o overhead de troca de contexto e frequentemente melhora o throughput de operacoes em bulk por uma ordem de magnitude. A clausula SAVE EXCEPTIONS permite que erros de DML (como violacoes de restricao) sejam coletados e analisados apos o processamento do lote, em vez de abortar no primeiro erro.

Pipelined Table Functions

Pipelined table functions produzem linhas de resultado iterativamente e as entregam diretamente ao chamador enquanto a funcao ainda esta executando. Isso possibilita consultas como SELECT * FROM TABLE(minha_funcao()), onde logica complexa de transformacao roda dentro de uma funcao mas o resultado fica disponivel diretamente em uma clausula FROM. Pipelined functions sao uteis para logica de transformacao que nao pode ser expressa de forma limpa em SQL puro mas ainda precisa ser consumida via SQL. Na migracao para SQL Server nao existe um equivalente direto; pipelined functions sao tipicamente substituidas por table-valued functions (TVFs) ou consultas baseadas em conjuntos.

PL/SQL · Bulk Collect com LIMIT e FORALL com SAVE EXCEPTIONS
DECLARE
    -- Tipos de colecao para operacoes em bulk
    TYPE t_id_tab    IS TABLE OF pedidos.pedido_id%TYPE;
    TYPE t_valor_tab IS TABLE OF pedidos.valor%TYPE;

    v_ids    t_id_tab;
    v_valores t_valor_tab;

    -- Cursor: seleciona todos os pedidos abertos
    CURSOR c_abertos IS
        SELECT pedido_id, valor
        FROM   pedidos
        WHERE  status = 'ABERTO'
        ORDER BY criado_em;

    -- Rastreamento de erros para SAVE EXCEPTIONS
    v_erros NUMBER;
    ex_dml  EXCEPTION;
    PRAGMA EXCEPTION_INIT(ex_dml, -24381);  -- codigo de erro para SAVE EXCEPTIONS
BEGIN
    OPEN c_abertos;
    LOOP
        -- Bulk collect: carrega ate 500 linhas de cada vez
        FETCH c_abertos BULK COLLECT INTO v_ids, v_valores LIMIT 500;
        EXIT WHEN v_ids.COUNT = 0;

        BEGIN
            -- Bulk DML: atualiza todas as linhas carregadas em uma unica chamada
            FORALL i IN 1 .. v_ids.COUNT SAVE EXCEPTIONS
                UPDATE pedidos
                SET    status       = 'PROCESSADO',
                       processado_em = SYSDATE,
                       valor_final   = v_valores(i) * 1.1  -- exemplo: adicionar taxa
                WHERE  pedido_id    = v_ids(i);

        EXCEPTION
            WHEN ex_dml THEN
                -- Avalia erros DML individuais sem abortar o lote inteiro
                v_erros := SQL%BULK_EXCEPTIONS.COUNT;
                FOR j IN 1 .. v_erros LOOP
                    -- Registra o codigo de erro e a linha com falha
                    INSERT INTO log_erros (codigo_erro, mensagem_erro, criado_em)
                    VALUES (
                        SQL%BULK_EXCEPTIONS(j).ERROR_CODE,
                        'Erro no pedido_id: ' || v_ids(SQL%BULK_EXCEPTIONS(j).ERROR_INDEX),
                        SYSDATE
                    );
                END LOOP;
        END;

        -- Commit por lote para distribuir a pressao sobre o redo log
        COMMIT;

    END LOOP;
    CLOSE c_abertos;
END;
/

BULK COLLECT LIMIT 500 busca em blocos; FORALL SAVE EXCEPTIONS grava todas as atualizacoes em uma chamada e captura erros individuais sem abortar o lote. Commit por lote evita transbordar segmentos de undo em grandes volumes de dados.

Bulk Collect e FORALL nao sao otimizacoes opcionais — sao padroes padrao para codigo PL/SQL critico de performance. Loops linha por linha com DML sao o assassino de performance mais comum no Oracle, e quase sempre podem ser acelerados em uma ordem de magnitude usando tecnicas de bulk.

Tratamento de Excecoes e Registro de Erros

O tratamento robusto de excecoes em PL/SQL e tao importante quanto em qualquer outra linguagem — e em ambientes Oracle frequentemente a diferenca entre um sistema que se recupera de forma limpa apos erros e um que deixa dados em estados inconsistentes. O PL/SQL distingue entre excecoes predefinidas (como NO_DATA_FOUND, TOO_MANY_ROWS, ZERO_DIVIDE), excecoes definidas pelo usuario com nome e o tratador generico OTHERS. Combinar esses mecanismos permite tratamento de erros granular que gerencia corretamente tanto excecoes esperadas (como nenhum resultado encontrado) quanto erros inesperados (como violacoes de restricao).

PRAGMA EXCEPTION_INIT e Excecoes Definidas pelo Usuario

PRAGMA EXCEPTION_INIT mapeia um codigo de erro Oracle (ORA-XXXXX) a um identificador de excecao nomeado, tornando os tratadores de excecao mais legiveis e permitindo respostas especificas a erros Oracle particulares sem precisar do tratador generico OTHERS. Excecoes definidas pelo usuario sao declaradas com DECLARE ... minha_excecao EXCEPTION; e lancadas com RAISE minha_excecao; — um padrao que comunica condicoes de erro de forma clara entre procedimentos de package.

Transacoes Autonomas para Registro de Erros

Um problema classico no tratamento de excecoes e o registro: se uma transacao falha e e revertida (ROLLBACK), quaisquer entradas de LOG feitas na mesma transacao tambem sao revertidas. A solucao e PRAGMA AUTONOMOUS_TRANSACTION no procedimento de registro: ele emite seu proprio COMMIT, independente da transacao externa. Esse padrao e padrao para tabelas de log de erros em sistemas Oracle e garante que registros de erro permanecam visiveis mesmo quando a transacao que causou a falha tenha sido completamente revertida.

SQLERRM, SQLCODE e DBMS_UTILITY.FORMAT_ERROR_BACKTRACE

SQLCODE e SQLERRM retornam o codigo de erro Oracle e a mensagem para a excecao mais recentemente lancada. DBMS_UTILITY.FORMAT_ERROR_BACKTRACE retorna o rastreamento completo de pilha, possibilitando a localizacao precisa de um erro em um package com multiplas camadas. Essa combinacao — SQLCODE, SQLERRM e FORMAT_ERROR_BACKTRACE — e a base de um log de erros significativo que torna o diagnostico de incidentes em producao substancialmente mais facil.

O tratamento de excecoes nao e luxo — e obrigatorio. Um sistema PL/SQL sem registro estruturado de erros transforma a analise post-mortem de incidentes de producao em adivinhacao. Transacoes autonomas, SQLERRM/SQLCODE e FORMAT_ERROR_BACKTRACE sao as ferramentas que tornam um log de erros genuinamente util.

Performance: Explain Plan, Hints, Indices

A analise de performance Oracle comeca com o explain plan. EXPLAIN PLAN FOR seguido de SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY) mostra quais operacoes o otimizador planeja executar: full table scans, index range scans, hash joins, nested loops, sort merge joins. Entender qual caminho de acesso e otimo em cada situacao e competencia central no trabalho de performance Oracle. Um full table scan nao e automaticamente ruim — para tabelas pequenas ou grandes conjuntos de resultados pode ser mais eficiente do que um index scan. Um nested loop e otimo para conjuntos externos pequenos, mas catastrofico para produtos cartesianos nao intencionais.

Bind Variables e Hard Parse

O problema de performance autoinfligido mais comum em ambientes Oracle e o hard parse excessivo pela falta de bind variables. Quando uma aplicacao Java envia consultas como SELECT * FROM clientes WHERE id = 12345 com valores literais incorporados, o Oracle deve analisar, otimizar e armazenar em cache cada texto de consulta distinto separadamente. A mesma instrucao com bind variables (WHERE id = :p1) e analisada uma vez, armazenada em cache no shared pool e reutilizada para execucoes subsequentes. Em sistemas com grande carga, a mudanca para bind variables pode reduzir significativamente a contencao de latch no shared pool e melhorar visivelmente a performance geral.

Hints do Otimizador

Hints sao diretivas para o Oracle Cost-Based Optimiser (CBO) que forcam ou preferem um plano de execucao especifico. Eles sao incorporados como comentarios imediatamente apos a palavra-chave SELECT, INSERT, UPDATE ou DELETE usando a forma /*+ HINT */. Hints comuns incluem INDEX (preferir este indice), NO_INDEX (evitar este indice), FULL (forcar full table scan), LEADING (determinar ordem de join) e USE_NL / USE_HASH / USE_MERGE (determinar metodo de join). Hints devem ser usados com cuidado: podem corrigir problemas de performance a curto prazo, mas impedem o otimizador de adaptar suas decisoes conforme as estatisticas mudam.

Oracle SQL · Explain plan, hints e bind variables
-- Passo 1: Gerar explain plan para uma consulta
EXPLAIN PLAN FOR
    SELECT /*+ INDEX(p idx_pedidos_cliente) LEADING(p c) USE_NL(c) */
           p.pedido_id,
           p.valor,
           c.nome         AS nome_cliente
    FROM   pedidos    p
    JOIN   clientes   c ON c.cliente_id = p.cliente_id
    WHERE  p.cliente_id = :p_cliente_id   -- bind variable em vez de literal
    AND    p.status     = 'ABERTO'
    AND    p.criado_em  >= TRUNC(SYSDATE) - 30;

-- Passo 2: Exibir o plano (formato TYPICAL com estimativas de custo)
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(
    format => 'TYPICAL +ROWS +BYTES +COST +PEEKED_BINDS'
));

-- Passo 3: Estatisticas de tempo de execucao para uma consulta ja executada
-- (do cursor cache, identificado via SQL_ID)
SELECT s.sql_id,
       s.executions,
       s.elapsed_time / NULLIF(s.executions, 0) / 1e6  AS media_seg,
       s.buffer_gets  / NULLIF(s.executions, 0)        AS media_bufgets,
       s.rows_processed / NULLIF(s.executions, 0)      AS media_linhas,
       s.sql_text
FROM   v$sql s
WHERE  s.sql_text LIKE '%pedidos%'
AND    s.executions > 0
ORDER BY media_seg DESC
FETCH FIRST 10 ROWS ONLY;

-- Passo 4: Identificar operacoes de full table scan no ultimo plano
-- (candidatos potenciais para criacao de indice)
SELECT d.operation,
       d.options,
       d.object_name,
       d.object_alias,
       d.cost,
       d.cardinality
FROM   plan_table d
WHERE  d.operation = 'TABLE ACCESS'
AND    d.options   = 'FULL'
ORDER BY d.cost DESC;

Explain plan com hints orienta o otimizador; bind variables previnem hard parse; v$sql fornece estatisticas reais de tempo de execucao do cursor cache para analise retrospectiva.

Estrategias de Indices no Oracle

Oracle suporta indices B-tree (padrao), indices bitmap, indices baseados em funcoes e indices compostos. Indices B-tree sao otimos para consultas seletivas que retornam poucas linhas; indices bitmap sao adequados para colunas com baixa cardinalidade (como colunas de status) em ambientes de data warehouse. Indices baseados em funcoes indexam o valor de uma expressao (como UPPER(nome)) e permitem buscas indexadas em valores transformados. Um erro frequente e aplicar funcoes a colunas indexadas na clausula WHERE — isso torna o indice inutilizavel. O monitoramento de indices Oracle (ALTER INDEX ... MONITORING USAGE) ajuda a identificar indices nao utilizados para remocao.

O tuning de performance no Oracle e iterativo: entender o explain plan, formular um hint ou alteracao de indice, medir o impacto, revisar as estatisticas. Bind variables sao a medida unica mais importante que desenvolvedores Java e .NET podem tomar. Hints sao um ultimo recurso — uteis quando usados corretamente, nao como substituto permanente de estatisticas ausentes.

Migracao Oracle para SQL Server

Migrar do Oracle para o SQL Server e um projeto com multiplas camadas que vai muito alem de simplesmente copiar dados. Mapeamento de esquema, conversao de tipos de dados, substituicao de sequences por IDENTITY ou objetos SEQUENCE do SQL Server, reescrita de logica PL/SQL em T-SQL e garantia de consistencia das aplicacoes sao tarefas separadas e exigentes. Eu realizei essas migracoes em varios projetos: numa empresa de quimica e industria onde uma paisagem Java/Oracle foi transferida para .NET/SQL Server, e numa instituicao financeira onde processos ETL Oracle foram substituidos por pipelines SSIS.

Migracao Oracle para SQL Server: modelo de abordagem em quatro fases com analise, conversao, migracao e homologacao

O modelo de abordagem esta estruturado em quatro fases: analise (inventario de esquema, escopo PL/SQL, mapeamento de tipos de dados), conversao (SSMA, PL/SQL para T-SQL, sequences para IDENTITY), migracao de dados (ETL/SSIS, validacao) e homologacao (comparacao de saida, testes de performance, operacao paralela).

Mapeamento de Tipos de Dados: Oracle para SQL Server

O mapeamento de tipos de dados e uma das primeiras e mais importantes tarefas numa migracao Oracle para SQL Server. Muitos tipos de dados Oracle nao tem um equivalente direto no SQL Server; outros tem um equivalente mas se comportam de forma sutilmente diferente. NUMBER e o tipo numerico generico do Oracle e mapeia para INT, BIGINT, DECIMAL ou FLOAT no SQL Server dependendo de precisao e escala. VARCHAR2 corresponde na maioria dos casos a VARCHAR(n) no SQL Server. DATE no Oracle armazena data e hora; o equivalente SQL Server DATETIME2 e mais preciso, mas DATE no SQL Server armazena apenas a data — uma fonte comum de erros. CLOB e BLOB tornam-se VARCHAR(MAX) e VARBINARY(MAX). RAW torna-se VARBINARY.

Oracle/T-SQL · Mapeamento de tipos de dados e equivalentes SSMA
-- ============================================================
-- LADO ORACLE: tabela exemplo com tipos de dados Oracle tipicos
-- ============================================================
CREATE TABLE pedidos_oracle (
    pedido_id    NUMBER(10)        NOT NULL,   -- INT / BIGINT no SQL Server
    cliente_id   NUMBER(10)        NOT NULL,
    valor        NUMBER(15, 2)     NOT NULL,   -- DECIMAL(15,2) no SQL Server
    descricao    VARCHAR2(500),               -- VARCHAR(500) no SQL Server
    observacoes  CLOB,                         -- VARCHAR(MAX) no SQL Server
    imagem       BLOB,                         -- VARBINARY(MAX) no SQL Server
    criado_em    DATE,                         -- DATETIME2(0) no SQL Server (inclui hora!)
    ativo        CHAR(1) DEFAULT 'S',          -- BIT ou CHAR(1) no SQL Server
    dados_brutos RAW(100),                     -- VARBINARY(100) no SQL Server
    CONSTRAINT pk_pedidos PRIMARY KEY (pedido_id)
);

-- Sequence como gerador de chave primaria (lado Oracle)
CREATE SEQUENCE seq_pedidos START WITH 1 INCREMENT BY 1 NOCACHE;

-- ============================================================
-- LADO SQL SERVER: tabela equivalente apos migracao com SSMA
-- ============================================================
CREATE TABLE pedidos_sqlserver (
    pedido_id    INT              NOT NULL IDENTITY(1,1),  -- IDENTITY substitui sequence
    cliente_id   INT              NOT NULL,
    valor        DECIMAL(15, 2)   NOT NULL,
    descricao    NVARCHAR(500)    NULL,        -- NVARCHAR para seguranca unicode
    observacoes  NVARCHAR(MAX)    NULL,        -- CLOB -> NVARCHAR(MAX)
    imagem       VARBINARY(MAX)   NULL,        -- BLOB -> VARBINARY(MAX)
    criado_em    DATETIME2(0)     NULL,        -- DATE Oracle tem hora -> DATETIME2
    ativo        BIT              NOT NULL DEFAULT 1,  -- CHAR(1) -> BIT
    dados_brutos VARBINARY(100)   NULL,        -- RAW -> VARBINARY
    CONSTRAINT pk_pedidos_ss PRIMARY KEY (pedido_id)
);

-- Equivalente MERGE: Oracle MERGE vs. SQL Server MERGE
-- Oracle:
MERGE INTO pedidos_oracle t
USING (SELECT 1001 AS id, 'PROCESSADO' AS status FROM DUAL) s
ON (t.pedido_id = s.id)
WHEN MATCHED     THEN UPDATE SET t.ativo = 'N'
WHEN NOT MATCHED THEN INSERT (pedido_id, cliente_id, valor, ativo)
                      VALUES (seq_pedidos.NEXTVAL, 0, 0, 'N');

-- SQL Server (apos migracao com SSMA):
MERGE INTO pedidos_sqlserver AS t
USING (VALUES (1001, 'PROCESSADO')) AS s (id, status)
ON (t.pedido_id = s.id)
WHEN MATCHED     THEN UPDATE SET t.ativo = 0
WHEN NOT MATCHED THEN INSERT (cliente_id, valor, ativo) VALUES (0, 0, 0);

O mapeamento mostra as principais conversoes de tipo: NUMBER para INT/DECIMAL, VARCHAR2 para NVARCHAR, CLOB para NVARCHAR(MAX), semantica de DATE Oracle, sequence para IDENTITY e variantes de sintaxe MERGE entre Oracle e SQL Server.

SQL Server Migration Assistant (SSMA)

SSMA para Oracle e a ferramenta de migracao gratuita da Microsoft que converte automaticamente esquema e codigo PL/SQL simples. O SSMA analisa o esquema Oracle, produz um relatorio de migracao com problemas e avisos, e gera scripts T-SQL DDL. Para codigo simples — tabelas, views, procedimentos simples — o SSMA e muito eficaz. Para packages PL/SQL complexos com logica de cursor, PRAGMA AUTONOMOUS_TRANSACTION, estado de package ou built-ins especificos do Oracle, o SSMA produz stubs com comentarios TODO que devem ser completados manualmente. O SSMA e um bom ponto de partida, nao uma ferramenta de migracao totalmente automatizada. O trabalho manual de seguimento requer conhecimento profundo tanto do Oracle quanto do SQL Server — exatamente a combinacao que eu trago.

Uma migracao Oracle para SQL Server e sempre um projeto com multiplas fases. O SSMA lida com a conversao mecanica; o trabalho real esta no mapeamento de logica especifica do Oracle — estado de package, sequences, consultas DUAL, ROWNUM, consultas hierarquicas Oracle — para equivalentes SQL Server. Essa traducao requer experiencia pratica em ambas as plataformas.

Conversao PL/SQL para T-SQL

Converter PL/SQL para T-SQL e a tarefa mais tecnicamente exigente numa migracao Oracle para SQL Server. Ambas as linguagens sao extensoes SQL procedurais, mas diferem tanto em sintaxe, semantica e construtos disponiveis que a traducao mecanica quase nunca funciona. Minha abordagem e sistematica: primeiro um inventario de todos os objetos PL/SQL com suas dependencias, depois uma classificacao por esforco de conversao, e em seguida a conversao em lotes priorizados com testes de regressao apos cada lote.

Principais Diferencas: Variaveis, Cursors, Excecoes

Em T-SQL, variaveis sao declaradas com DECLARE @var TIPO e atribuidas com SET @var = ... ou SELECT @var = .... O PL/SQL nao distingue entre SET e SELECT. Cursors existem em T-SQL (DECLARE CURSOR, OPEN, FETCH, CLOSE, DEALLOCATE), mas raramente sao usados na pratica por problemas de performance — alternativas baseadas em conjuntos sao quase sempre preferidas. Excecoes em T-SQL usam TRY/CATCH com THROW, ERROR_NUMBER() e ERROR_MESSAGE(). O conceito de PRAGMA EXCEPTION_INIT nao existe; ERROR_NUMBER() retorna o codigo de erro do SQL Server, mas nao ha mapeamento direto 1:1 de codigos ORA- Oracle para codigos de erro SQL Server.

Construtos Oracle sem Equivalente T-SQL Direto

Alguns construtos Oracle requerem solucoes criativas em T-SQL: DUAL (a tabela de uma linha do Oracle usada em SELECT 1 FROM DUAL) torna-se simplesmente SELECT 1 em T-SQL, sem clausula FROM. ROWNUM para consultas top-N torna-se TOP n ou ROW_NUMBER() OVER (...). CONNECT BY PRIOR para consultas hierarquicas torna-se uma CTE recursiva com WITH ... AS (... UNION ALL ...). DECODE() mapeia para CASE WHEN. NVL() mapeia para ISNULL() ou COALESCE(). TO_DATE(), TO_CHAR() e TRUNC() tem equivalentes T-SQL (CONVERT, FORMAT, CAST, DATETRUNC). Estado de package — variaveis que reteem seus valores entre chamadas dentro de uma sessao — nao tem equivalente direto no SQL Server; requer tabelas de contexto, tabelas temporarias ou contexto de sessao no nivel da aplicacao.

PL/SQL -> T-SQL · Exemplo de conversao: procedimento com cursor
-- ============================================================
-- ORIGINAL: Procedimento Oracle PL/SQL com cursor e excecao
-- ============================================================
CREATE OR REPLACE PROCEDURE oracle_processar_faturas(
    p_vencimento DATE,
    p_processado OUT NUMBER
) IS
    CURSOR c_vencidas IS
        SELECT f.fatura_id, f.valor, c.email
        FROM   faturas   f
        JOIN   clientes  c ON c.cliente_id = f.cliente_id
        WHERE  f.vencimento <= p_vencimento
        AND    f.status = 'ABERTO';
    v_linha   c_vencidas%ROWTYPE;
    v_contagem NUMBER := 0;
BEGIN
    OPEN c_vencidas;
    LOOP
        FETCH c_vencidas INTO v_linha;
        EXIT WHEN c_vencidas%NOTFOUND;
        UPDATE faturas
        SET status = 'COBRADO', cobrado_em = SYSDATE
        WHERE fatura_id = v_linha.fatura_id;
        v_contagem := v_contagem + 1;
    END LOOP;
    CLOSE c_vencidas;
    COMMIT;
    p_processado := v_contagem;
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK;
        RAISE;
END;
/

-- ============================================================
-- CONVERSAO: Stored procedure T-SQL no SQL Server
-- Sem cursor necessario: UPDATE baseado em conjunto com clausula OUTPUT
-- ============================================================
CREATE OR ALTER PROCEDURE dbo.processar_faturas
    @vencimento  DATE,
    @processado  INT OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    -- Variavel de tabela para capturar resultados OUTPUT
    DECLARE @atualizadas TABLE (fatura_id INT);

    BEGIN TRY
        BEGIN TRANSACTION;

        -- UPDATE baseado em conjunto: substitui completamente o loop de cursor Oracle
        -- A clausula OUTPUT captura as IDs de faturas atualizadas
        UPDATE f
        SET    f.status    = 'COBRADO',
               f.cobrado_em = GETDATE()
        OUTPUT inserted.fatura_id INTO @atualizadas (fatura_id)
        FROM   dbo.faturas f
        WHERE  f.vencimento <= @vencimento
        AND    f.status     = 'ABERTO';

        -- Retorna o numero de linhas processadas
        SET @processado = @@ROWCOUNT;

        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
        -- Propaga ao chamador (equivalente a RAISE em PL/SQL)
        THROW;
    END CATCH;
END;
GO

O loop de cursor Oracle e substituido em T-SQL por um UPDATE baseado em conjunto com a clausula OUTPUT — mais simples, mais rapido e T-SQL idiomatico. TRY/CATCH com THROW mapeia diretamente para o padrao EXCEPTION WHEN OTHERS THEN RAISE do Oracle.

Sequences para IDENTITY e Sequences SQL Server

Sequences Oracle (CREATE SEQUENCE ... NEXTVAL) sao mapeadas para o SQL Server de duas formas: colunas IDENTITY para chaves primarias simples de auto-incremento, e sequences SQL Server (CREATE SEQUENCE, NEXT VALUE FOR ...) para casos em que o valor e necessario antes do INSERT. O SSMA converte sequences Oracle para IDENTITY por padrao, o que e correto para a maioria dos casos. Quando sequences sao usadas em codigo PL/SQL fora de instrucoes INSERT — por exemplo para numerar lotes ou gerar chaves para varias tabelas simultaneamente — um objeto SEQUENCE do SQL Server e o mapeamento mais adequado.

A conversao PL/SQL para T-SQL requer entendimento profundo de ambas as linguagens. A conversao mecanica via SSMA fornece um ponto de partida, mas construtos especificos do Oracle como estado de package, consultas hierarquicas, padroes de bulk collect e transacoes autonomas devem ser traduzidos manual e cuidadosamente para equivalentes T-SQL.

Tooling: SQL*Plus, SQL Developer, TOAD

O tooling para trabalho com banco de dados Oracle evoluiu consideravelmente ao longo dos anos. SQL*Plus, a ferramenta de linha de comando que Oracle fornece desde seus primordios, continua sendo a ferramenta de escolha para automacao de scripts, processamento em lote e consultas rapidas ad hoc em ambientes de servidor sem interface grafica. SQL Developer e o cliente grafico gratuito da Oracle com capacidades de IDE: debugger PL/SQL, modelador de dados, assistente de migracao e integracao com Data Pump. TOAD da Quest e o padrao da industria para desenvolvimento Oracle profissional e trabalho de DBA: extensa analise de codigo, comparacao de esquema, diagnostico de performance e recursos de codificacao em equipe. Eu usei intensivamente todas as tres ferramentas e as aplico contextualmente dependendo da tarefa e do ambiente.

SQL*Plus para Automacao

SQL*Plus pode ser totalmente controlado por scripts: CONNECT, START, SPOOL, SET SERVEROUTPUT ON e a sintaxe EXECUTE permitem a execucao de fluxos de trabalho PL/SQL completos a partir da linha de comando. Em ambientes Unix/Linux — onde muitas grandes instalacoes Oracle rodam — SQL*Plus e a ferramenta natural para shell scripts que orquestram operacoes de banco de dados. Em projetos de migracao, eu uso SQL*Plus para automatizar dumps de esquema, exportacoes de dados e consultas de validacao.

TOAD: Diagnostico de Performance e Analise de Codigo

TOAD oferece recursos que vao muito alem da execucao basica de consultas: Schema Compare permite a comparacao de objetos de banco de dados entre ambientes; Code Analysis verifica codigo PL/SQL para anti-padroes de qualidade e performance; o SQL Optimizer fornece exibicao grafica de explain plan e comparacao de planos de execucao; Team Coding suporta troca de codigo versionado. Em projetos com orcamento de licenca disponivel, TOAD e a ferramenta mais eficiente para desenvolvimento PL/SQL intensivo e analise de performance.

Data Pump, SQL*Loader e Ferramentas Externas

Para migracao e transferencia de dados, Data Pump (expdp/impdp), SQL*Loader e ferramentas ETL externas sao os instrumentos essenciais. Data Pump produz exportacoes logicas no formato proprietario Oracle (dump files) e e o metodo recomendado para migracao de esquema entre instancias Oracle. SQL*Loader carrega eficientemente arquivos de dados externos (CSV, formato fixo) em tabelas Oracle e e particularmente util na fase inicial de carga de projetos de migracao. Para transferir dados do Oracle para SQL Server, SSIS com conector Oracle OLE DB ou ODBC, Azure Data Factory com conector Oracle ou ferramentas dedicadas de migracao como SSMA sao as opcoes disponiveis.

A ferramenta nao e a competencia, mas a ferramenta certa para a tarefa acelera substancialmente o trabalho. SQL*Plus para automacao de scripts, SQL Developer para desenvolvimento interativo, TOAD para analise intensiva de performance e codigo — essa distincao orienta cada projeto Oracle que conduzo.

ANSI SQL para Reports Multiplataforma

Em ambientes onde reports ou consultas precisam rodar contra multiplos sistemas de banco de dados — Oracle, SQL Server, Teradata, MySQL — codigo SQL compativel com ANSI oferece uma vantagem significativa de manutencao. Crystal Reports, SSRS e outras ferramentas de relatorios podem consultar fontes de dados Oracle diretamente; se essas consultas forem ANSI-compliant, o mesmo codigo tambem roda contra fontes SQL Server ou Teradata. Eu escrevo SQL para relatorios deliberadamente em conformidade ANSI onde possivel: joins padrao em vez da sintaxe Oracle de join (+), CASE em vez de DECODE, COALESCE em vez de NVL, EXTRACT em vez de TO_CHAR para componentes de data, CAST em vez de funcoes de conversao proprietarias.

Sintaxe Especifica Oracle e seus Equivalentes ANSI

Oracle introduziu historicamente muitas extensoes de sintaxe proprietarias ainda encontradas em codigo mais antigo: o operador de outer join antigo (+) em vez de LEFT/RIGHT/FULL OUTER JOIN; DECODE em vez de CASE WHEN; NVL em vez de COALESCE; ROWNUM para top-N em vez de ROW_NUMBER() OVER (...); START WITH ... CONNECT BY PRIOR para consultas hierarquicas em vez de CTEs recursivas. Esse codigo mais antigo funciona no Oracle mas em nenhum outro lugar. Onde o SQL de relatorios precisa ser independente de plataforma, deve ser refatorado para sintaxe ANSI.

Abordagem Pratica para Consultas Multiplataforma

Minha abordagem para consultas de relatorios multiplataforma: joins padrao ANSI, CASE WHEN, COALESCE, funcoes de data ISO (EXTRACT, CURRENT_DATE, CURRENT_TIMESTAMP), funcoes de agregacao padrao e ROW_NUMBER()/RANK()/DENSE_RANK() para consultas analiticas. O que deve permanecer especifico de plataforma (como ROWID, hints de particionamento, funcoes especificas Oracle como LISTAGG ou REGEXP_SUBSTR) e isolado em views SQL especificas de plataforma ou parametros. Ferramentas de relatorios como Crystal Reports podem entao mudar para um backend diferente com minimo retrabalho.

Codigo SQL compativel com ANSI e um investimento em independencia. Organizacoes usando Oracle hoje e migrando para SQL Server ou Snowflake amanha vao apreciar ter escrito consultas ANSI-compliant. Sintaxe proprietaria economiza um pouco de digitacao agora, mas custa tempo de migracao mais tarde.

Abordagem de Colaboracao

Todo projeto Oracle comeca com analise cuidadosa. Antes de fazer recomendacoes ou escrever codigo, eu construo um quadro completo: qual versao Oracle esta em uso? Quais packages PL/SQL existem e quais sao suas dependencias? Quais problemas de performance sao conhecidos? Se uma migracao esta planejada: qual e o cronograma, quais aplicacoes dependem do sistema Oracle, quais processos ETL devem ser substituidos? Essas perguntas devem ser respondidas antes de discutir solucoes tecnicas.

  • Analise: versao Oracle, inventario de esquema, dependencias PL/SQL, problemas de performance conhecidos
  • Priorizacao: codigo critico de performance, caminho de migracao, riscos legados
  • Desenvolvimento/tuning: implementacao incremental com ciclos de revisao e testes de regressao
  • Migracao: analise SSMA, conversao, migracao de dados, operacao paralela, homologacao
  • Documentacao: anotacao PL/SQL, guia de migracao, documentacao operacional
  • Transferencia de conhecimento: treinamento para a equipe interna, entrega de scripts e procedimentos

Trabalho remotamente, em modelo hibrido ou presencialmente. Para desenvolvimento PL/SQL, analise de performance e conversao SSMA, o trabalho remoto e suficiente e eficiente. Para workshops iniciais de esquema, cutover de migracoes sensiveis e go-live da plataforma de destino, a presenca fisica frequentemente tem mais valor. Trabalho em alemao, ingles ou portugues — todos fluentemente, incluindo para discussoes tecnicas aprofundadas.

O que diferencia projetos Oracle de outros projetos de banco de dados e a profundidade das dependencias legadas. Sistemas Oracle geralmente estao em execucao ha anos ou decadas; o codigo PL/SQL cresceu organicamente, os autores ja foram embora ha muito tempo, e a documentacao e escassa. Nesses ambientes, a capacidade de entender codigo alheio rapidamente e altera-lo ou migra-lo com seguranca e mais importante do que escrever novo codigo de acordo com uma especificacao. Eu desenvolvi e apliquei essa capacidade em varios projetos de migracao de sistemas legados.

Projetos Oracle requerem paciencia com codigo legado e precisao em migracoes. Solucoes rapidas que ignoram peculiaridades especificas do Oracle causam problemas mais tarde. Minha abordagem: analise cuidadosa, implementacao incremental, decisoes documentadas — e um cronograma de projeto realista.

Servicos Oracle Tipicos

Meu portfolio de servicos Oracle abrange desenvolvimento, tuning de performance, migracao e migracao de dados. Dependendo das necessidades do projeto, cubro areas individuais ou o escopo completo da analise ao go-live em producao.

  • Desenvolvimento PL/SQL: packages, procedimentos, funcoes, cursors, bulk collect, excecoes
  • Tuning de performance: analise de explain plan, hints de otimizador, projeto de indices, bind variables
  • Migracao Oracle para SQL Server: analise de esquema, SSMA, mapeamento de tipos de dados
  • Conversao PL/SQL para T-SQL: cursors, excecoes, estado de package, sequences para IDENTITY
  • Migracao de dados: ETL com SSIS, conector Oracle JDBC, validacao, operacao paralela
  • Tooling: automacao de scripts SQL*Plus, SQL Developer, diagnostico de performance TOAD
  • Refatoracao ANSI SQL para reports multiplataforma (Crystal Reports, SSRS)
  • ODI (Oracle Data Integrator): fundamentos, interfaces, conceitos de knowledge module
  • Substituicao ETL Oracle por SSIS: conversao de processos Java+Oracle para pipelines SSIS
  • Documentacao e transferencia de conhecimento: anotacao PL/SQL, guias de migracao

Um foco particular sao projetos de migracao em que sistemas legados Java/Oracle sao movidos para .NET/SQL Server. Nesses projetos combino conhecimento Oracle de origem (PL/SQL, modelo de dados, logica de negocio no codigo) com competencia de destino SQL Server (T-SQL, SSIS, administracao SSMS) e experiencia .NET (templates T4 para geracao de codigo, testes tSQLt para logica migrada). Essa combinacao reduz substancialmente o overhead de coordenacao entre especialistas Oracle, desenvolvedores SQL Server e desenvolvedores .NET.

No setor de seguros, trabalhei com ODI (Oracle Data Integrator): interfaces, knowledge modules (KM) para diferentes estrategias e tecnologias de carga, e orquestracao de processos de migracao de dados. La tambem o objetivo era tipicamente substituir a infraestrutura ETL Oracle proprietaria por pipelines SSIS padronizados no SQL Server.

Projetos de referencia anonimizados selecionados

Quimica / Industria

Migracao Java/Oracle para .NET/SQL Server · templates T4 · tSQLt · rotinas ETL

Migracao completa de uma aplicacao Java com backend Oracle para .NET/SQL Server. O trabalho incluiu analise do esquema Oracle e da logica PL/SQL, mapeamento para estruturas de dados SQL Server, desenvolvimento de rotinas ETL para transferencia de dados, uso de templates T4 para camadas de acesso a dados geradas por codigo, e verificacao da logica migrada por meio de testes de regressao tSQLt. Mapeamento de tipos de dados, uso do SSMA e conversao PL/SQL para T-SQL foram elementos centrais do projeto.

Instituicao Financeira / Caixa Economica

Substituicao Java+Oracle por SSIS · cargas de arquivo texto · SSDT · PowerShell

Substituicao de um sistema ETL baseado em Java com backend Oracle por pipelines SSIS no SQL Server. O projeto incluiu analise das consultas Oracle existentes e procedimentos PL/SQL, sua traducao em componentes de fluxo de dados SSIS, construcao de processos de carga de arquivo texto e automacao do deployment via SSDT e PowerShell. O redesenho de performance de pipelines ETL criticos foi parte importante do projeto.

Seguradora / Resseguradora

ODI / Oracle · desenvolvimento PL/SQL · migracao de dados · migracao para SSIS

Desenvolvimento e manutencao de packages PL/SQL para processos de migracao de dados no setor de seguros, combinado com configuracao de interfaces ODI e knowledge modules. Posteriormente migrou os processos Oracle/ODI para SSIS/SQL Server: analise de equivalencia, comparacao de saida e go-live incremental da nova plataforma rodando em paralelo com o sistema legado.

Logistica / Grupo Empresarial

PL/SQL no contexto Teradata/Informatica · garantia de qualidade · BTEQ

Atuacao em um grande ambiente empresarial com paisagem de banco de dados heterogenea: Oracle PL/SQL para logica de transformacao em nivel de banco de dados, Teradata e Informatica PowerCenter para o processo ETL central. O foco estava na garantia de qualidade dos fluxos de dados, reconciliacao entre fontes Oracle e destinos Teradata, e documentacao da paisagem de processos.

Perguntas frequentes sobre Oracle e PL/SQL

Qual e a diferenca entre PL/SQL e T-SQL?

PL/SQL e a extensao SQL procedural da Oracle; T-SQL e o equivalente da Microsoft para SQL Server. Ambos permitem logica procedural no banco de dados, mas diferem significativamente: PL/SQL tem packages com specification/body, PRAGMA AUTONOMOUS_TRANSACTION, cursors explicitos com BULK COLLECT e ref cursors. T-SQL tem TRY/CATCH, operacoes em bulk baseadas em conjuntos e MERGE, mas sem estado de package e sem transacoes autonomas. A conversao requer conhecimento profundo de ambas as linguagens.

Com quais versoes Oracle voce tem experiencia?

Oracle 8i ate 19c de projetos reais. Experiencia particularmente intensa com 11g, 12c e 18c/19c. Conheco os comportamentos especificos de versao relevantes para migracoes: padroes de otimizador alterados, novos recursos PL/SQL e as especificidades multitenant do 12c em diante.

Voce pode realizar uma migracao Oracle para SQL Server?

Sim. Esta e uma oferta central. Combino conhecimento Oracle de origem (PL/SQL, esquema, tipos de dados) com competencia SQL Server de destino (T-SQL, SSIS, administracao). Uso o SSMA como auxilio de analise e conversao; o trabalho manual de seguimento em construtos especificos Oracle (estado de package, consultas hierarquicas, padroes de bulk collect) e a tarefa central real.

O que e Bulk Collect e por que e importante?

BULK COLLECT carrega multiplas linhas em uma unica chamada da engine SQL em uma colecao PL/SQL em vez de le-las uma por uma. Isso reduz drasticamente o overhead de troca de contexto entre a engine PL/SQL e a engine SQL. Combinado com FORALL para escrita, operacoes em bulk que demoram minutos linha a linha podem ser reduzidas a segundos.

Como voce aborda explain plans e hints de otimizador?

Explain plan mostra o caminho de execucao planejado; uso DBMS_XPLAN.DISPLAY com formato detalhado. Uso hints quando o otimizador escolhe um plano subotimo apesar de estatisticas corretas — como intervencao cirurgica, nao como substituto de estatisticas ausentes. Bind variables sao a medida mais importante contra contencao no shared pool.

Voce pode substituir processos ETL Oracle por SSIS?

Sim. Fiz exatamente isso em varios projetos: substituindo processos ETL baseados em Oracle (packages PL/SQL, interfaces ODI) por pipelines SSIS. O ponto critico e a validacao de saida: o pipeline SSIS deve produzir o mesmo resultado que o processo Oracle antes de encerrar a operacao paralela.

O que e ANSI SQL e por que e importante para reports multiplataforma?

ANSI SQL e o padrao internacional suportado por todos os principais sistemas de banco de dados. Sintaxe especifica Oracle como (+)-joins, DECODE ou ROWNUM so funciona no Oracle. Escrever consultas de relatorios em forma ANSI-compliant (sintaxe JOIN, CASE WHEN, COALESCE, ROW_NUMBER()) significa que as mesmas consultas rodam contra Oracle, SQL Server e Teradata — uma grande vantagem ao mudar de plataforma.

Voce tem experiencia com ODI (Oracle Data Integrator)?

Sim. Tenho experiencia com fundamentos ODI: interfaces, knowledge modules (staging area KM, integration KM), procedimentos e orquestracao de processos ODI. Em um projeto de seguradora, ODI era a plataforma ETL cujos processos foram posteriormente migrados para SSIS. Esse conhecimento ajuda a entender e traduzir corretamente processos de origem ODI.

Em quais idiomas voce trabalha?

Alemao, ingles e portugues — todos fluentemente, incluindo para discussoes tecnicas aprofundadas sobre PL/SQL, T-SQL e arquitetura de banco de dados.

Contato

Solicitação de projeto

Precisa de apoio em ETL, Data Vault, arquitetura de BI, SQL Server ou Azure?

Remoto · Híbrido · Alemanha · UE · Brasil · Meio período · Tempo integral