Descobrir tabela/campo que dispara o erro ORA-01438

Dicas do Oracle Forms Builder - Blocos, Itens, LOV, Canvas, Triggers, comandos, PLL, d2kwutil, FMB, Alert, menus, etc
Responder
pyro
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 323
Registrado em: Qui, 21 Set 2006 10:21 am
Localização: Barala - TT

Pessoal, tenho um Form 6i, digamos bem antigo e inflado, nele existe um botão que faz uma infinidade de validações, somas e mais uma diversidade de ações e neste tempo vai efetuando o insert em diversas tabelas.

Agora ele emperrou em disparar o erro ORA-01438, sei que está querendo gravar um valor maior que o suportado pelo campo, mas existe uma forma de eu saber em qual tabela/campo está disparando o erro?

Tipo, quando o insert ocorrer que disparar o erro tem como capturar também onde exatamente estava a gravação?
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

Ola Pyro,

Você poderia criar no seu schema uma trigger para capturar os erros de banco de dados.

Faz algum tempo, fiz algo parecido para um sistema onde trabalho.

Eu não tenho exatamente o link original onde esta solução é apresentada,
mas posso te passar a minha adaptação.

Seja como for, o autor da solução não foi eu, e recomendo que você
teste antes em algum ambiente de desenvolvimento:


Os passos:

A) Crie uma tabela para capturar os erros:

Selecionar tudo

CREATE TABLE TB_MNSM_SSTA
(
ID_MNSM_SSTA       NUMBER(12)     NOT NULL,
IN_TIPO_MNSM_SSTA  CHAR(1)        NOT NULL,
DH_MNSM_SSTA       DATE           NOT NULL,
NO_MDLO            VARCHAR2(30)   NULL, 
NO_USRO_BNCO       VARCHAR2(30)   NULL,
NO_TRML            VARCHAR2(50)   NULL,
CD_MNSM_ERRO_STMA  VARCHAR2(10)   NULL,
TE_MSNM_SSTA       VARCHAR2(4000) NULL,
TE_STMT_ERRO_STMA  CLOB);
B) Crie uma sequence para popular a coluna de sequencia da tabela acima:

Selecionar tudo

CREATE SEQUENCE SQ_MNSM_SSTA
       START WITH 1
       INCREMENT BY 1
       MINVALUE 1
       MAXVALUE 999999999999
       CACHE 20
       ORDER
       CYCLE;
C) Crie uma procedure para registrar dados na tabela de captura dos erros:

Selecionar tudo

CREATE OR REPLACE PROCEDURE SP_GRA_MNSM_STMA
(PR_IN_TIPO_MNSM_SSTA       TB_MNSM_SSTA.IN_TIPO_MNSM_SSTA%TYPE DEFAULT 'L',
 PR_DH_MNSM_SSTA            TB_MNSM_SSTA.DH_MNSM_SSTA%TYPE      DEFAULT SYSDATE,
 PR_NO_MDLO                 TB_MNSM_SSTA.NO_MDLO%TYPE,
 PR_NO_USRO_BNCO            TB_MNSM_SSTA.NO_USRO_BNCO%TYPE,
 PR_NO_TRML                 TB_MNSM_SSTA.NO_TRML%TYPE     ,
 PR_CD_MNSM_ERRO_STMA       TB_MNSM_SSTA.CD_MNSM_ERRO_STMA%TYPE,
 PR_TE_MSNM_SSTA            TB_MNSM_SSTA.TE_MSNM_SSTA%TYPE,
 PR_TE_STMT_ERRO_STMA       TB_MNSM_SSTA.TE_STMT_ERRO_STMA%TYPE
)
-----------------------------------------------------
--- PROCEDURE : SP_GRA_MNSM_STMA
--- DESCRICAO : Esta procedure gera mensagens de log
---             na tabela TB_MNSM_SSTA, que seria
---             uma tabela geral para log de mensagens
---             do . Os tipos de mensagem que
---             podem ser gravadas são:
---               - [E] ERRO  : Mensagens de ERRO
---               - [D] DEBUG : Mensagens de DEBUG
---               - [L] LOG   : Mensagens em geral
--- PARAMETROS: PR_IN_TIPO_MNSM_SSTA  => Indicator tipo mensagem (E/D/L)
---             PR_DH_MNSM_SSTA       => Data Hora mensage
---             PR_NO_MDLO            => Nome Modulo 
---             PR_NO_USRO_BNCO       => Nome Usuario Banco
---             PR_NO_TRML            => Terminal Conexao Banco
---             PR_CD_MNSM_ERRO_STMA  => Codigo Mensagem Erro
---             PR_TE_MSNM_SSTA       => Descricao Mensagem Sistema
---             PR_TE_STMT_ERRO_STMA => Comando SQL executado (para o caso de erros)
-----------------------------------------------------
IS
BEGIN
  DELETE
    FROM TB_MNSM_SSTA
   WHERE DH_MNSM_SSTA < SYSDATE-30;

  INSERT
    INTO TB_MNSM_SSTA
        (ID_MNSM_SSTA     ,
         IN_TIPO_MNSM_SSTA,
         DH_MNSM_SSTA     ,
         NO_MDLO          ,
         NO_USRO_BNCO          ,
         NO_TRML               ,
         CD_MNSM_ERRO_STMA,
         TE_MSNM_SSTA     ,
         TE_STMT_ERRO_STMA)
 VALUES (SQ_MNSM_SSTA.NEXTVAL,
         PR_IN_TIPO_MNSM_SSTA,
         PR_DH_MNSM_SSTA     ,
         PR_NO_MDLO          ,
         PR_NO_USRO_BNCO          ,
         PR_NO_TRML               ,
         PR_CD_MNSM_ERRO_STMA,
         PR_TE_MSNM_SSTA     ,
         PR_TE_STMT_ERRO_STMA);

END SP_GRA_MNSM_STMA;
/
D) Crie a trigger de captura dos erros. Note que você precisa informar o nome do schema (texto entre <..>):

Selecionar tudo

CREATE OR REPLACE TRIGGER TGR_CPTA_ERRO
AFTER SERVERERROR  ON <COLOQUE_O_NOME_DE_SEU_SCHEMA>.SCHEMA
-----------------------------------------------------
--- TRIGGER   : TGR_CPTA_ERRO
--- DESCRICAO : Esta trigger captura a maioria dos
--              erros "ORA" (nem todos) que evetualmente
--              ocorram no banco de dados
-----------------------------------------------------
DECLARE
   PRAGMA AUTONOMOUS_TRANSACTION;
   SQL_TEXT ORA_NAME_LIST_T;
   V_STMT CLOB;
   N NUMBER;
BEGIN
  --
  N := ORA_SQL_TXT(SQL_TEXT);
  --
  IF N >= 1 THEN
     FOR I IN 1..N LOOP
         V_STMT := V_STMT || SQL_TEXT(I);
     END LOOP;
  END IF;
  --
  FOR N IN 1..ORA_SERVER_ERROR_DEPTH LOOP
      --
      -- log only potential SQL Injection attempts
      -- alternatively it's possible to log everything
      -- insert the attempt including the SQL statement into a table
      SP_GRA_MNSM_STMA (PR_IN_TIPO_MNSM_SSTA =>  'E',                             PR_DH_MNSM_SSTA      =>  SYSDATE,
                             PR_NO_MDLO           =>  'ERRO BANCO',
                             PR_NO_USRO_BNCO           =>  ORA_LOGIN_USER,
                             PR_NO_TRML                =>  ORA_CLIENT_IP_ADDRESS,
                             PR_CD_MNSM_ERRO_STMA =>  ORA_SERVER_ERROR(N),
                             PR_TE_MSNM_SSTA      =>  ORA_SERVER_ERROR_MSG(N),
                             PR_TE_STMT_ERRO_STMA =>  V_STMT);
      -- send the information via email to the DBA
      --  <<Insert your PLSQL code for sending emails >>
      COMMIT;
  END LOOP;
END TGR_SCHEMA_DDL;
/
Tudo isso tem que ser feito no mesmo schema onde seu forms irá acessar.

Uma vez implantado, faça um teste para ver se ele te mostra o comando onde ocorre o erro.

O comando que gerou o erro ficará armazenado na coluna CLOB.

Você pode simplificar radicalmente tudo que te passei. Creio que criando uma trigger e uma tabela, você consegue capturar os erros.

Abraços e boa sorte,

Sergio Coutinho
pyro
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 323
Registrado em: Qui, 21 Set 2006 10:21 am
Localização: Barala - TT

Cara, obrigado, vou analisar o que me passou e implementar por aqui.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 17 visitantes