Aula 16: Views e Materialized Views no Oracle
A capacidade de abstrair, simplificar e acelerar o acesso aos dados é o que separa um desenvolvedor SQL funcional de um especialista em bancos de dados Oracle. Nesta aula, vamos nos aprofundar em duas estruturas que transformam a maneira como você projeta consultas e otimiza sistemas: Views e Materialized Views. Se você já se deparou com consultas quilométricas repetidas em múltiplas aplicações ou com relatórios que demoram minutos para serem executados por conta de agregações pesadas, saiba que a solução definitiva está exatamente aqui. Em nossos projetos na JRT Technology Solutions, utilizamos diariamente Views para criar camadas de segurança e simplificação lógica, enquanto as Materialized Views são as grandes responsáveis por reduzir a latência de dashboards e sistemas de apoio à decisão em ambientes críticos.
O objetivo desta aula é fornecer a você um domínio completo e prático sobre esses dois objetos, indo além da teoria superficial. Você vai aprender a criar Views simples e complexas, compreender as limitações de operações DML sobre elas e aplicar cláusulas como WITH CHECK OPTION e WITH READ ONLY. Na segunda metade da aula, mergulharemos nas Materialized Views, cobrindo desde a criação e configuração de logs de materialized view até os diferentes modos de refresh (FAST, COMPLETE e FORCE), criação de índices, e as condições para habilitar o poderoso Query Rewrite. Tudo isso será demonstrado com comandos reais, saídas de terminal verificáveis e exemplos tirados do dia a dia de um DBA ou desenvolvedor Oracle.
Por que isso importa? Em sistemas de grande porte, repetir lógica de negócio em cada consulta é um convite à inconsistência e à manutenção caótica. Uma View encapsula essa lógica em um único objeto, garantindo que todas as aplicações enxerguem os dados exatamente da mesma forma. Já as Materialized Views são a ferramenta definitiva para o cenário de “consultas pesadas e dados que não precisam estar 100% em tempo real”. Elas armazenam fisicamente o resultado de uma consulta e podem ser atualizadas de forma incremental ou completa, permitindo que um relatório que antes demorava 20 minutos seja entregue em milissegundos. Ao final desta aula, você será capaz de decidir com propriedade quando usar cada uma dessas estruturas, como implementá-las e como resolver os erros mais comuns que surgem no ambiente Oracle.
Os pré-requisitos para esta aula incluem o conhecimento adquirido nas aulas anteriores do nosso curso, especialmente domínio de SELECT, JOINs, funções de agregação e criação de objetos básicos. Você precisará de acesso a uma instância Oracle (12c ou superior) com privilégios para criar VIEW, MATERIALIZED VIEW, e, idealmente, acesso ao DBA_HIST_SNAPSHOT ou tabelas de exemplo como as do schema HR ou SCOTT. Se você está utilizando o Oracle XE gratuito, todas as funcionalidades demonstradas aqui são perfeitamente suportadas. Prepare seu terminal SQL*Plus, SQL Developer ou qualquer cliente SQL de sua preferência e venha dominar dois dos objetos mais subestimados e poderosos do ecossistema Oracle.
O que você vai aprender nesta aula
- O conceito fundamental de Views como tabelas virtuais e suas limitações em operações DML.
- Criação e gerenciamento de Views simples, complexas e do tipo Inline View (subconsultas na cláusula FROM).
- Utilização obrigatória de WITH CHECK OPTION e WITH READ ONLY para impor restrições de segurança e integridade.
- Como as Materialized Views diferem das Views comuns por armazenarem dados fisicamente.
- Passo a passo completo para criar uma Materialized View com logs e configurar refresh rápido, completo ou sob demanda.
- O papel do Query Rewrite e como ele pode transformar consultas do usuário sem tocar no código-fonte da aplicação.
- Comandos de verificação no dicionário de dados (USER_VIEWS, USER_MVIEWS) para auditar o estado das suas views.
- Diagnóstico e solução de pelo menos quatro erros clássicos que nossos especialistas da JRT Technology Solutions encontram em produção.
Pré-requisitos e Ambiente
Antes de iniciarmos os procedimentos práticos, certifique-se de que seu ambiente atenda aos requisitos listados abaixo. Não se preocupe com instalações complexas — se você já está com o Oracle funcionando e acessível, está pronto para começar.
- Oracle Database 12c ou superior: As funcionalidades de Materialized View e Query Rewrite exigem Enterprise Edition, mas as Views tradicionais e refresh completo funcionam em qualquer edição, incluindo XE.
- Usuário com privilégios adequados: Para criar views tradicionais, você precisa apenas de CREATE VIEW. Para materialized views, é necessário CREATE MATERIALIZED VIEW e, dependendo da estratégia de refresh, CREATE ANY TABLE ou quotas em tablespace. Para habilitar query rewrite, você precisará de GLOBAL QUERY REWRITE ou QUERY REWRITE no seu schema.
- Tabelas de exemplo: Utilizaremos as tabelas EMP e DEPT do schema SCOTT. Caso elas não existam, você pode criá-las rapidamente executando o script $ORACLE_HOME/rdbms/admin/utlsampl.sql ou criá-las manualmente com base nos comandos que fornecerei.
- Ferramenta cliente: SQL*Plus, Oracle SQL Developer, DBeaver ou qualquer ferramenta capaz de executar scripts SQL. Mantenha a sessão logada como um usuário que atenda aos pré-requisitos de privilégio.
Views: A Tabela Virtual e a Abstração da Lógica de Negócio
Uma View no Oracle é, essencialmente, uma consulta SQL armazenada no dicionário de dados. Ela não contém dados físicos por si só — a cada vez que você faz uma consulta a uma view, o Oracle reescreve seu comando internamente, substituindo a referência à view pelo texto da consulta que a define. Essa característica é conhecida como “transparência lógica”. Uma view comum (não-materializada) é ideal quando você precisa: (1) simplificar consultas complexas para desenvolvedores e aplicações; (2) restringir colunas ou linhas visíveis a determinados usuários, funcionando como uma camada de segurança; e (3) isolar mudanças estruturais em tabelas-base, evitando que alterações físicas quebrem aplicações legadas que referenciam a view. No entanto, é fundamental compreender que operações DML (INSERT, UPDATE, DELETE) sobre views são restritas. O Oracle só permite modificação direta via view em casos específicos, como quando a view acessa apenas uma única tabela e não contém funções de agregação, DISTINCT, GROUP BY, CONNECT BY ou operadores de conjunto (UNION, MINUS). Views que envolvem múltiplas tabelas, colunas virtuais ou pseudocolunas são inerentemente não-atualizáveis.
Em nossos projetos na JRT Technology Solutions, a arquitetura de segurança de muitos sistemas é construída inteiramente sobre views. Por exemplo, uma tabela de funcionários pode conter informações sensíveis como salário e CPF. Criamos uma view pública que expõe apenas nome, cargo e departamento, e atribuímos permissão de SELECT nessa view aos usuários de relatórios, sem jamais conceder acesso direto à tabela base. Isso resolve dois problemas ao mesmo tempo: simplifica o modelo de segurança e garante que aplicações não acidentalmente obtenham dados sensíveis. Outro caso clássico é a criação de uma view que unifica dados de diversas fontes (via UNION ALL) para sistemas legados que esperam uma única tabela — o encapsulamento da lógica de união na view torna a migração transparente e de baixo risco.
Para consolidar este entendimento, vamos criar nossa primeira view. Acesse o SQL*Plus e execute a criação das tabelas-base caso ainda não as tenha.
Criando e Gerenciando Views Simples
O comando para criar uma view é extremamente direto: CREATE OR REPLACE VIEW nome_da_view AS consulta_sql. A cláusula OR REPLACE é uma boa prática obrigatória, pois permite recriar ou alterar a definição da view sem precisar excluí-la previamente. Para views simples, que mapeiam diretamente colunas de uma única tabela, a criação é trivial. Vamos utilizar a tabela EMP para criar uma view que exponha apenas funcionários do departamento 20 e oculte a coluna de comissão. Primeiro, confirme que a tabela existe e contém dados:
-- Conectar como usuário SCOTT ou equivalente
SELECT empno, ename, deptno, sal, comm FROM emp WHERE deptno = 20;
Agora, a criação da view, que chamaremos de VW_EMP_DEPT20. Observe o uso de WITH CHECK OPTION, uma cláusula extremamente importante que impede operações de INSERT ou UPDATE que fariam com que linhas deixassem de ser visíveis pela própria view. Isso garante a integridade conceitual da camada de abstração.
CREATE OR REPLACE VIEW vw_emp_dept20 AS
SELECT empno, ename, job, mgr, hiredate, sal
FROM emp
WHERE deptno = 20
WITH CHECK OPTION; -- impede inserção ou atualização que mudaria deptno != 20
Com a view criada, você pode testar uma consulta simples e uma tentativa de inserção que viole a condição:
SELECT * FROM vw_emp_dept20;
Se tentarmos inserir um funcionário no departamento 30 através da view, o Oracle rejeitará a operação imediatamente, prevenindo inconsistências lógicas. Isso é o WITH CHECK OPTION em ação. Experimente executar:
INSERT INTO vw_emp_dept20 (empno, ename, job, hiredate, sal, deptno)
VALUES (9999, 'TESTE', 'CLERK', SYSDATE, 1000, 30);
O erro esperado será ORA-01402: view WITH CHECK OPTION where-clause violation, informando que a inserção violou a condição da view. Para ambientes onde absolutamente nenhuma modificação deve ser feita através da view, utilizamos WITH READ ONLY. Substitua a definição:
CREATE OR REPLACE VIEW vw_emp_dept20 AS
SELECT empno, ename, job, mgr, hiredate, sal
FROM emp WHERE deptno = 20
WITH READ ONLY;
Agora qualquer tentativa de DML resultará em ORA-42399: cannot perform a DML operation on a read-only view. Esses pequenos detalhes evitam que aplicações mal-intencionadas ou bugs causem estragos na base de dados.
Views Complexas e Operações DML
Quando uma View envolve JOINs, funções de agregação ou cláusula GROUP BY, ela é classificada como complexa e, na maioria dos casos, não suporta DML direto. Isso acontece porque o Oracle não pode deduzir de forma unívoca como propagar uma modificação para as tabelas base sem ambiguidade. Por exemplo, considere uma view que lista cada departamento com o total de salários e a quantidade de funcionários. Sua definição seria algo como:
CREATE OR REPLACE VIEW vw_dept_sumario AS
SELECT d.deptno, d.dname, COUNT(e.empno) qtd_func, NVL(SUM(e.sal),0) total_sal
FROM dept d LEFT JOIN emp e ON d.deptno = e.deptno
GROUP BY d.deptno, d.dname;
Executar DELETE FROM vw_dept_sumario WHERE deptno = 10; resulta no erro ORA-01732: data manipulation operation not legal on this view, porque a view não preserva a chave primária da tabela base de forma unívoca e porque a operação de deleção não pode ser mapeada para as linhas físicas de origem. A lição aqui é que views de agregação são estritamente de consulta. No entanto, existe um caso intermediário: views com JOINs de duas tabelas que preservam todas as colunas de junção podem ser atualizáveis se o Oracle conseguir determinar a tabela-alvo corretamente, mas isso exige que as restrições de chave estrangeira estejam presentes e a tabela-alvo não tenha ambuiguidades. Na prática, recomenda-se fortemente que em sistemas de produção as views complexas sejam tratadas como somente-leitura, e que qualquer DML seja feito diretamente nas tabelas base via procedimentos controlados.
Entendendo Materialized Views: o Contêiner Físico de Resultados
Enquanto uma View comum é apenas uma “janela” para os dados reais, uma Materialized View (também chamada de snapshot em versões antigas) armazena uma cópia física do resultado da consulta em disco. Isso significa que a consulta não precisa ser reexecutada do zero cada vez que alguém acessa a view — os dados já estão lá, materializados. A grande mágica acontece no mecanismo de atualização, ou refresh. O Oracle oferece três modos principais: COMPLETE, que apaga e recarrega todos os dados do zero; FAST, que aplica apenas as mudanças incrementais desde o último refresh, utilizando um materialized view log nas tabelas-base; e FORCE, que tenta o refresh rápido e, se não for possível, executa o completo. Existe ainda o refresh ON COMMIT (transacional) ou ON DEMAND (manual/agendado via DBMS_MVIEW ou jobs).
Ao longo dos projetos da JRT Technology Solutions, empregamos Materialized Views em duas situações arquetípicas: (1) data warehouses onde grandes relatórios agregados precisam de respostas em sub-segundos, e o ETL noturno é responsável por manter a materialized view atualizada via refresh completo; (2) sistemas transacionais que, através de refresh rápido com logs, mantêm sumários quase em tempo real para dashboards operacionais. A decisão entre esses dois cenários depende da disponibilidade de materialized view logs e da presença de funções que impedem o refresh rápido, como COUNT(DISTINCT) ou joins complexos sem suporte. Outro conceito crucial é o Query Rewrite: quando habilitado, o otimizador do Oracle pode automaticamente redirecionar consultas escritas contra as tabelas-base para a materialized view pré-calculada, sem que o usuário ou a aplicação precise saber que a materialized view existe. Isso é uma ferramenta de otimização transparente extremamente poderosa.
Criando e Configurando Materialized Views Passo a Passo
Para demonstrar todo o processo de forma realista, vamos construir um cenário onde manteremos um sumário de vendas (ainda que não tenhamos essa tabela, usaremos a agregação de EMP). Primeiro, precisamos habilitar o suporte a refresh rápido criando um MATERIALIZED VIEW LOG na tabela base. Esse log armazena as chaves das linhas modificadas e, opcionalmente, os valores antigos e novos das colunas de interesse.
Execute os passos numerados abaixo. Você precisa estar conectado como usuário com privilégios adequados. Vamos também incluir a coluna ROWID para logs, embora o recomendado atualmente seja usar chave primária.
- Certifique-se de que a tabela EMP tenha uma chave primária. Se não tiver, crie uma usando ALTER TABLE emp ADD CONSTRAINT pk_emp PRIMARY KEY (empno);
- Crie o log de materialized view na tabela base EMP, incluindo as colunas que serão sumarizadas (salário) e indicando que novas linhas serão registradas:
CREATE MATERIALIZED VIEW LOG ON emp
WITH PRIMARY KEY, ROWID (sal, deptno)
INCLUDING NEW VALUES;
Esse comando cria um objeto interno chamado MLOG$_EMP que o Oracle usará para rastrear as mudanças. A opção INCLUDING NEW VALUES é necessária para muitos casos de refresh rápido, pois o Oracle precisa saber o novo valor das colunas para aplicar as modificações corretamente.
Agora, crie a materialized view propriamente dita, com refresh rápido agendado a cada 5 minutos e QUERY REWRITE habilitado para que o otimizador possa usá-la automaticamente.
CREATE MATERIALIZED VIEW mv_emp_salario_dept
BUILD IMMEDIATE
REFRESH FAST ON DEMAND
ENABLE QUERY REWRITE
AS
SELECT deptno, SUM(sal) total_sal, COUNT(*) qtd
FROM emp
GROUP BY deptno;
A cláusula BUILD IMMEDIATE instrui o Oracle a popular a materialized view imediatamente. Se você quisesse apenas definir o objeto sem preenchê-lo inicialmente, usaria BUILD DEFERRED. Note que não especificamos START WITH e NEXT porque estamos usando ON DEMAND; o refresh será feito manualmente ou via DBMS_MVIEW. Caso queira refresh automático periódico, você poderia usar REFRESH FAST START WITH SYSDATE NEXT SYSDATE+5/(24*60), mas isso cria um job internamente. Para ambientes de produção, recomendamos o uso do DBMS_SCHEDULER para maior controle, como veremos nas dicas avançadas.
Verifique a criação e o estado da materialized view consultando o dicionário de dados:
SELECT mview_name, refresh_mode, refresh_method, staleness, query_rewrite_enabled
FROM user_mviews WHERE mview_name = 'MV_EMP_SALARIO_DEPT';
A saída esperada deve ser semelhante a:
MVIEW_NAME REFRESH_MODE REFRESH_METHOD STALENESS QUERY_REWRITE_ENABLED
-------------------- ------------ --------------- ---------- ---------------------
MV_EMP_SALARIO_DEPT DEMAND FAST FRESH Y
Refresh de Materialized Views: Operação e Diagnóstico
O coração da eficiência das Materialized Views reside no processo de refresh. Vamos executar um refresh manual e analisar os parâmetros que controlam a atomicidade e consistência. O método principal é através da procedure DBMS_MVIEW.REFRESH. Para fazer o refresh da nossa view recém-criada, execute:
EXEC DBMS_MVIEW.REFRESH('MV_EMP_SALARIO_DEPT', 'F');
O segundo parâmetro ‘F’ indica refresh rápido (FAST). Se por algum motivo o refresh rápido não for possível, ele falhará com o erro ORA-12034 em vez de recorrer ao refresh completo, garantindo que você detecte problemas de configuração. Outros parâmetros comuns incluem ‘C’ para completo, ‘?’ para forçar, e a possibilidade de passar uma lista de views separadas por vírgula. É altamente recomendável que você sempre monitore a coluna STALENESS após operações de refresh. Se ela estiver NEEDS_COMPILE ou UNUSABLE, sua materialized view pode estar inválida e não será considerada pelo otimizador.
Agora, insira um novo registro na tabela EMP e execute o refresh novamente para ver a mágica incremental:
INSERT INTO emp (empno, ename, deptno, sal) VALUES (8888, 'NOVO', 20, 4500);
COMMIT;
EXEC DBMS_MVIEW.REFRESH('MV_EMP_SALARIO_DEPT', 'F');
SELECT * FROM mv_emp_salario_dept ORDER BY deptno;
Você observará que o total do departamento 20 foi incrementado em 4500. O que ocorre internamente é que o Oracle consulta o MLOG$_EMP, identifica a chave modificada e recalcula apenas a linha da materialized view correspondente, sem varrer a tabela inteira. Esse é o poder do refresh rápido.
Índices e Desempenho em Materialized Views
Uma vez que a materialized view armazena dados fisicamente, você pode — e deve — criar índices para acelerar consultas que a acessam. O Oracle automaticamente cria um índice para a coluna que atende à cláusula GROUP BY se houver uma restrição de chave primária, mas muitas vezes você precisará de índices adicionais. Por exemplo, se as consultas frequentemente filtram por total_sal ou ordenam por qtd, crie índices explicitamente:
CREATE INDEX idx_mv_sal ON mv_emp_salario_dept(total_sal);
CREATE INDEX idx_mv_qtd ON mv_emp_salario_dept(qtd);
Além disso, você pode querer criar a materialized view com uma cláusula STORAGE específica e tablespace segregado para melhor performance de I/O. Em data warehouses, a prática comum é manter as materialized views em tablespaces separadas das tabelas de staging.
Outra dica de desempenho essencial é habilitar o Query Rewrite de forma global ou no nível da sessão, para que o otimizador substitua consultas às tabelas-base pela materialized view sem que você precise alterar o código do relatório. Para testar se o rewrite está funcionando, execute uma consulta que deveria ser reescrita e verifique o plano de execução:
EXPLAIN PLAN FOR
SELECT deptno, SUM(sal) FROM emp GROUP BY deptno;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
Procure pela operação MAT_VIEW REWRITE ACCESS FULL (ou INDEX) na saída. Caso ela não apareça mesmo após habilitar o rewrite, verifique se o parâmetro de otimizador QUERY_REWRITE_ENABLED está TRUE (padrão) e se a materialized view tem a opção ENABLE QUERY REWRITE. Se as restrições de RELY e ENFORCED de chaves estrangeiras não estiverem satisfeitas, o rewrite pode falhar silenciosamente.
Segurança e Permissões em Views e Materialized Views
A segurança é um dos pilares que tornam as Views ferramentas indispensáveis. No Oracle, um usuário pode ter permissão de SELECT em uma view sem ter acesso nenhum às tabelas subjacentes, desde que o proprietário da view possua os privilégios necessários (GRANT) e não haja revogações em cadeia. Isso é conhecido como “acesso por meio de objetos de definição do proprietário”. No entanto, cuidado com a armadilha dos privilégios herdados: se você concede acesso a uma view que usa SELECT * FROM e depois adiciona uma coluna à tabela base, a definição da view pode ficar inválida até ser recompilada. Para evitar surpresas, especifique sempre as colunas explicitamente.
Em Materialized Views, a segurança se torna mais delicada porque os dados estão replicados. Se os dados da materialized view forem confidenciais, você precisa controlar o acesso à própria materialized view como faria com qualquer tabela. Além disso, o log de materialized view contém informações transacionais que, se expostas, podem revelar padrões de alteração. Restrinja o acesso ao log apenas ao proprietário do esquema. Em ambientes de missão crítica na JRT Technology Solutions, seguimos a política de nunca conceder acesso direto às tabelas bases de produção, utilizando views (ou materialized views) como a única interface para leitura, e procedures com validação para escrita — isso garante uma camada de auditoria e validação de negócio impossível de ser contornada.
Verificando a Instalação / Testando a Configuração
Para garantir que todos os conceitos foram aplicados corretamente e que seu ambiente está respondendo como esperado, realize esta sequência de verificações. Cada comando é acompanhado de uma saída esperada para que você possa comparar com o seu terminal.
1. Liste todas as views clássicas do seu schema:
SELECT view_name, text_length FROM user_views WHERE view_name LIKE 'VW_%';
VIEW_NAME TEXT_LENGTH
-------------------- -----------
VW_EMP_DEPT20 145
2. Verifique as materialized views e seus estados:
SELECT mview_name, staleness, compile_state, refresh_mode FROM user_mviews;
MVIEW_NAME STALENESS COMPILE_STATE REFRESH_MODE
---------------------- ---------- -------------- ------------
MV_EMP_SALARIO_DEPT FRESH VALID DEMAND
3. Confirme se o log de materialized view está capturando alterações. Insira uma linha e consulte a tabela de log (o nome é MLOG$_EMP ou similar em maiúsculas):
INSERT INTO emp (empno, ename, deptno, sal) VALUES (7777, 'TESTLOG', 30, 5000);
COMMIT;
SELECT COUNT(*) FROM mlog$_emp;
COUNT(*)
----------
1
4. Teste o refresh rápido e veja se a materialized view foi atualizada:
EXEC DBMS_MVIEW.REFRESH('MV_EMP_SALARIO_DEPT','F');
SELECT * FROM mv_emp_salario_dept WHERE deptno = 30;
DEPTNO TOTAL_SAL QTD
------ ---------- ------
30 15500 7
Se todas as verificações corresponderem, sua configuração de Views e Materialized Views está perfeitamente funcional e pronta para produção.
Erros Comuns e Como Resolver
Durante a implementação e manutenção de Views e Materialized Views, alguns erros se repetem com frequência em ambientes Oracle. Nossos especialistas da JRT Technology Solutions compilaram uma lista dos quatro problemas mais recorrentes, suas causas e soluções efetivas:
-
ORA-00942: table or view does not exist
Sintoma: Você recebe este erro ao tentar executar uma consulta contra uma view ou ao criar uma materialized view que referencia uma tabela inexistente.
Causa: A tabela base não existe no schema atual ou o usuário não tem privilégios de leitura sobre ela. Pode acontecer quando o objeto foi removido ou está em um schema diferente sem GRANT.
Solução: Verifique o nome da tabela com SELECT * FROM all_tables WHERE table_name=’NOME’;. Se a tabela existir em outro schema, você deve prefixar com o nome do schema (schema.tabela) ou criar um sinônimo público/privado e garantir que os privilégios foram concedidos (GRANT SELECT ON schema.tabela TO usuario;). -
ORA-01732: data manipulation operation not legal on this view
Sintoma: Ao tentar executar INSERT, UPDATE ou DELETE em uma view, a operação é rejeitada.
Causa: A view é complexa (envolve joins, funções de agregação, DISTINCT, GROUP BY ou SET OPERATORS) e, portanto, o Oracle não pode mapear a modificação de forma unívoca para a tabela base.
Solução: Redefina a view como somente-leitura (WITH READ ONLY) para deixar clara sua intenção. Se for estritamente necessário modificar dados, crie procedimentos que atuem diretamente nas tabelas base, contornando a view. -
ORA-12008: error in materialized view refresh path
Sintoma: O refresh de uma materialized view falha com este erro genérico, frequentemente acompanhado de um stack trace.
Causa: Geralmente, há um problema com o log da materialized view (log corrompido ou ausente) ou a consulta que define a view contém elementos não suportados para refresh rápido, como COUNT(DISTINCT) sem logs adicionais ou joins complexos.
Solução: Consulte o DBA_MVIEW_ANALYSIS para ver a razão exata das restrições. Recrie o log com INCLUDING NEW VALUES e simplifique a consulta da materialized view para usar apenas agregações suportadas (SUM, COUNT, MIN, MAX, AVG). Caso persista, faça um refresh completo para restaurar a consistência e monitore os logs de alerta. -
ORA-12034: materialized view log on “SCOTT”.”EMP” younger than last refresh
Sintoma: O refresh rápido falha informando que o log foi reinicializado ou truncado após o último refresh.
Causa: Alguém truncou ou recriou o log de materialized view após o último refresh bem-sucedido. O Oracle não consegue mais fazer o refresh rápido porque a sequência de mudanças foi perdida.
Solução: Execute um refresh completo (COMPLETE) para sincronizar a materialized view com os dados atuais. Depois, o refresh rápido voltará a funcionar normalmente. Certifique-se de restringir permissões no log para evitar exclusões acidentais.
Boas Práticas e Dicas Avançadas com Views e Materialized Views
Ao longo de centenas de projetos, refinamos um conjunto de práticas que fazem toda a diferença na estabilidade e desempenho de sistemas Oracle. A primeira delas é: nunca utilize SELECT * na definição de uma view ou materialized view. Se uma coluna for adicionada ou removida da tabela base, a view pode se tornar inválida ou gerar resultados inesperados. Especifique sempre a lista exata de colunas. Para materialized views que utilizam refresh rápido, sempre crie o log na tabela base imediatamente após a criação da tabela, pois adicioná-lo depois em produção exige refreshes completos que podem travar o sistema.
Quanto ao agendamento de refresh, prefira o DBMS_SCHEDULER sobre a cláusula START WITH na definição da materialized view. Isso porque o scheduler oferece maior flexibilidade — você pode criar janelas de manutenção, cadeias de dependências e tratamento de erros robusto. Em nossas implementações na JRT Technology Solutions, criamos uma job que executa um DBMS_MVIEW.REFRESH de todas as materialized views de um determinado schema, com tratamento de exceções e logging customizado. Exemplo de criação do scheduler:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'REFRESH_MVIEWS_JOB',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN DBMS_MVIEW.REFRESH(''MV_EMP_SALARIO_DEPT'',''F''); END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=MINUTELY; INTERVAL=5',
enabled => TRUE);
END;
/
Outra dica avançada é a utilização de materialized views aninhadas. Você pode criar uma materialized view que se baseia em outra materialized view para construir camadas de sumarização. Isso é comum em data warehouses onde você tem uma camada de grãos finos e outra de alto nível. No entanto, atenção redobrada à ordem de refresh: a view base deve ser atualizada antes da view dependente. Utilize o parâmetro ATOMIC_REFRESH => FALSE na DBMS_MVIEW.REFRESH para permitir consultas durante o refresh (non-atomic), sacrificando a consistência transacional por disponibilidade em ambientes de leitura intensa.
Por fim, monitore periodicamente o dicionário de dados. A consulta abaixo retorna views que estão em estado inválido ou que precisam de recompilação:
SELECT object_name, status FROM user_objects WHERE object_type = 'VIEW' AND status != 'VALID'
UNION ALL
SELECT mview_name, compile_state FROM user_mviews WHERE compile_state != 'VALID';
Manter esses objetos sempre válidos evita dores de cabeça na madrugada de uma virada de ano fiscal.
Comparativo: Views vs Materialized Views — Quando Usar Cada Uma
Para consolidar o conhecimento, apresentamos uma tabela comparativa que nossos consultores usam como referência rápida em campo. Ela sumariza as principais características e cenários de uso de Views e Materialized Views.
| Característica | View | Materialized View |
|---|---|---|
| Armazenamento físico | Nenhum (apenas definição SQL) | Cópia física dos dados |
| Desempenho de consulta | Igual ao das tabelas base | Pode ser ordens de magnitude mais rápido |
| Atualização | Sempre reflete dados atuais | Depende do refresh (pode ter latência) |
| Suporte a DML | Limitado a views simples | Comum (é uma tabela física) |
| Query Rewrite | Não aplicável | Sim, se habilitado |
| Cenário típico | Segurança e abstração lógica | Relatórios, data warehouse, sumários |
Resumo da Aula 16
Chegamos ao final da Aula 16 com um vasto repertório sobre Views e Materialized Views. Aprendemos que as Views são objetos lógicos que encapsulam consultas, proveem segurança e simplificam o acesso, mas têm restrições severas de DML. Vimos como criar desde uma view simples com WITH CHECK OPTION até visões complexas inatualizáveis. Nas Materialized Views, exploramos o armazenamento físico, a criação de logs, os modos de refresh (FAST, COMPLETE, FORCE), a habilitação de Query Rewrite e a construção de índices para desempenho. Verificamos o estado dos objetos no dicionário de dados e diagnosticamos erros como ORA-01732, ORA-12008 e ORA-12034, oferecendo soluções práticas para cada um.
As boas práticas discutidas — evitar SELECT *, usar logs desde o início, preferir DBMS_SCHEDULER e monitorar estados — são o verdadeiro diferencial em ambientes profissionais. Lembre-se de que a escolha entre uma view e uma materialized view não é binária: muitos sistemas se beneficiam de ambas coexistindo. Na JRT Technology Solutions, frequentemente construímos camadas de views de segurança que apontam para materialized views sumarizadas, unindo o melhor dos dois mundos.
Na próxima aula (Aula 17: Índices e Otimização de Consultas no Oracle), você aprenderá a usar os índices para levar o desempenho das consultas — inclusive as que atacam suas materialized views recém-criadas — a um novo patamar. Abordaremos índices B-tree, bitmap, funcionais e o uso do Oracle Optimizer com estatísticas atualizadas. Não perca!
Quer aprender na prática com especialistas?
A JRT Technology Solutions oferece treinamentos e implementação de Oracle SQL para equipes corporativas.