# Oracle ERRORSTACK: como descobrir o SQL exato por trás de um ORA-00942

Quem administra Oracle Golden Gate há algum tempo já encontrou situações em que algum replicat apresenta o seguinte erro:

![](https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/6713d704-b6b1-4879-8293-05f0a5ada811.png align="center")

`2026-09-22 18:44:46 ERROR OGG-00664 Error 942 on OCI call [ORA] - ORA-00942: table or view does not exist Help: https://docs.oracle.com/error-help/db/ora-00942/.`

`2026-09-22 18:44:48 WARNING OGG-00543 Unexpected threading library failure. Error code 16 (Device or resource busy).`

O grande problema deste erro, é que ele não é especifico, o problema começa quando você não sabe **qual tabela ou view**, **qual SQL**, ou até mesmo **qual sessão** está provocando o erro durante o start do replicat.

> `REPLICAT ABENDED REP1 INTEGRATED 00:00:00 00:30:13`

erro indicava claramente um problema de acesso a um objeto, mas não informava em quais objeto do banco rs.

Foi aí que usei um recurso extremamente útil do Oracle Database: **EVENT + ERRORSTACK**.

![](https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/7f8ffa35-6cc2-469b-b810-9fec0152ac6e.png align="center")

Este recuso funciona como um **gatilho**:

```plaintext
EVENT 942 habilitado
        ↓
Oracle continua trabalhando normalmente
        ↓
alguma sessão recebe ORA-00942
        ↓
evento é disparado
        ↓
Oracle gera o trace
        ↓
capturamos o contexto do erro
```

Nesse caso estamos dizendo ao Oracle:

> Quando ocorrer um `ORA-00942`, gere um error stack com informações detalhadas sobre a sessão no momento do erro.

![](https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/b9d027f6-e711-42b2-afd7-b1cc7b323b4d.png align="center")

Pronto !!

Agora sabemos quais objetos ele está relacionando os erros:

![](https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/b09dc90d-82fd-4088-b135-13f689f99afa.png align="center")

E finalmente apareceu o SQL que estava falhando:

```plaintext
SELECT ...
FROM sys."_BASE_USER" u,
     sys.obj$         o,
     sys.cdef$        cd,
     sys.ccol$        cc,
     sys.con$         c,
     sys.col$         col
WHERE ...
```

Pronto.

Saímos de:

```plaintext
ORA-00942
table or view does not exist
```

para:

> O Apply Receiver do GoldenGate está executando uma consulta contra objetos internos do Data Dictionary.

Ao executar os seguintes selects descobri a ausencia de grants corretos diretamente em objetos pertencentes ao schema SYS.

![](https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/4eaf31c5-0676-42f8-b83b-2581d8156bdf.png align="center")

### Mas o usuário tinha SELECT ANY TABLE

Essa foi outra parte interessante do troubleshooting.

O `GGADMIN` já possuía:

```plaintext
SELECT ANY TABLE
```

Mas mesmo assim estava tomando o seguinte erro:

**ORA-00942: table or view does not exist**

Isso acontece porque objetos internos do **Oracle Data Dictionary**, especialmente objetos do schema `SYS`, possuem proteção específica.

`SELECT ANY TABLE` não deve ser interpretado como acesso irrestrito a todas as tabelas internas do Data Dictionary.

Testando com `GGADMIN`, alguns desses objetos também retornavam `ORA-00942`.

A documentação do Oracle diferencia `SELECT ANY TABLE` de privilégios que permitem acesso ao Data Dictionary. Para esse cenário, o privilégio que resolveu o acesso necessário foi:

```plaintext
GRANT SELECT ANY DICTIONARY TO GGADMIN;
```

Após o grant, os objetos anteriormente inacessíveis passaram a ser consultados e o Integrated Replicat conseguiu prosseguir.

![](https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/a1e7942b-11ab-45b1-a6bd-247130ed5d26.png align="center")

Em seguida meu processo no golden gate saiu do status de ABEND para RUNNING e problema foi resolvido.

![](https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/cc4fdc20-b486-4d69-b730-5fc94fc18aab.png align="center")

Status Detalhado:

![](https://cdn.hashnode.com/uploads/covers/69835211e3aecdfd224c568a/70d2be8a-53ce-4763-8f6f-0602471ae6a4.png align="center")

## Cuidados em produção

`ALTER SYSTEM SET EVENTS` deve ser utilizado com critério.

Se você configurar:

```plaintext
ALTER SYSTEM SET EVENTS
'942 trace name errorstack level 3';
```

e o ambiente estiver gerando milhares de `ORA-00942`, poderá produzir grande quantidade de dados de diagnóstico.

Por isso, prefiro trabalhar com uma janela controlada:

1.  Identificar erro reproduzível
    
2.  Habilitar event
    
3.  Reproduzir
    
4.  Desabilitar imediatamente
    
5.  Analisar o trace
    

Também é importante avaliar o escopo e impacto apropriados para o ambiente antes de utilizar eventos de diagnóstico em produção.

# Conclusão

Às vezes o erro apresentado pela aplicação é apenas a ponta do problema.

Neste caso começamos com:

```plaintext
ORA-00942
```

O GoldenGate não mostrava qual objeto estava causando a falha.

Com um `ERRORSTACK`, conseguimos descobrir:

```plaintext
qual sessão
    ↓
qual módulo
    ↓
qual componente GoldenGate
    ↓
qual SQL
    ↓
quais objetos
    ↓
qual privilégio estava faltando
```

Para quem trabalha com Oracle, esse tipo de recurso muda bastante a abordagem de troubleshooting.

Em vez de:

> “Qual tabela será que está faltando?”

passamos a perguntar ao próprio banco:

> **“Oracle, capture o contexto exatamente no momento em que esse erro acontecer.”**

E foi isso que nos levou da mensagem genérica `ORA-00942` até a causa real do problema.
