Rafael
Por acaso eu dispunha de uma base 9i, e fiz alguns testes.
Consultando os foruns, notei que no 9i o erro ORA-01438 ocorre exclusivamente com campos numéricos. Segue um exemplo:
Selecionar tudo
SQL> CREATE TABLE LIXO (COLUNA CHAR(1));
Tabela criada.
SQL> INSERT INTO LIXO VALUES ('AA');
INSERT INTO LIXO VALUES ('AA')
*
ERRO na linha 1:
ORA-01401: inserted value too large for column
SQL> DROP TABLE LIXO;
Tabela eliminada.
SQL> CREATE TABLE LIXO (COLUNA NUMBER(1));
Tabela criada.
SQL> INSERT INTO LIXO VALUES (10);
INSERT INTO LIXO VALUES (10)
*
ERRO na linha 1:
ORA-01438: value larger than specified precision allows for this column
Repeti estes testes com os mesmos resultados para VARCHAR2 e NUMBER(i,d). Só campos numéricos retornam este código de erro.
Acho que você conseguiria identificar rapidamente a coluna executando o comando de INSERT no SQL*PLUS.
Informando a coluna ou não, ele aponta com um asterisco (*) justamente o ponto onde o comando deu pau:
Selecionar tudo
SQL> CREATE TABLE LIXO (COLUNA_A NUMBER(1), COLUNA_B NUMBER(2));
Tabela criada.
SQL> INSERT INTO LIXO (COLUNA_A,COLUNA_B) VALUES (1,100);
INSERT INTO LIXO (COLUNA_A,COLUNA_B) VALUES (1,100)
*
ERRO na linha 1:
ORA-01438: value larger than specified precision allows for this column
SQL> INSERT INTO LIXO VALUES (1,100);
INSERT INTO LIXO VALUES (1,100)
*
ERRO na linha 1:
ORA-01438: value larger than specified precision allows for this column
O que você então poderia fazer neste caso? Não sei se o seu ETL executa comandos de INSERT na base de dados ORACLE.
Se for este o caso, e você não sabe exatamente qual INSERT deu pau, você pode criar uma TRIGGER que capture erros de banco de dados.
Siga os passos abaixo para detectar este erro:
Selecionar tudo
-- Criando uma tabela para capturar erros
CREATE TABLE TB_ERRO
(DT_ERRO DATE,
CM_SQL CLOB);
-- Criando uma trigger para capturar erros em um determinado schema
-- Substitua SYSTEM pelo schema onde a tabela a ser carregada se encontra
CREATE OR REPLACE TRIGGER TGR_CPTA_ERRO
AFTER SERVERERROR ON SYSTEM.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
--
INSERT
INTO TB_ERRO
(DT_ERRO,
CM_SQL)
VALUES
(SYSDATE,
V_STMT);
COMMIT;
END LOOP;
END TGR_CPTA_ERRO;
/
As operações de ETL devem ser executadas com o usuário dono do schema da tabela. Você não precisa executar ela até o fim. Basta que ocorra o primeiro errp ORA-01438.
Feito isso, você pode consultar a TB_ERRO para identificar o comando capturado no campo CLOB.
Copie o comando SQL executado, abra uma sessão SQL*PLUS e faça um "paste" do comando. Por mais colunas que tenha a tabela, ela vai indicar com um asterisco o ponto onde o problema ocorre. Se forem geradas muitas linhas de comando, tente alterar a sessão com um
SET LINESIZE 5000
e
SET TRIMSPOOL ON
, para ver se o asterisco pode ser visualizado exatamente na posição que ocorre o erro.
Pode ser que exista algum problema com os seus campos núméricos. Não exatamente os NUMBER(I.D). Pode ser que uma coluna SQLSERVER do tipo INT não esteja corretamente dimensionada no ORACLE (ex: NUMBER(38)).
Eu localizei um documento da Microsoft que faz uma comparação entre os tipos do SQLSERVER x ORACLE. O link se situa em:
http://msdn.microsoft.com/en-us/library/ms151817.aspx
Espero que consiga resolver os seus problemas.
Boa sorte,
Sergio Coutinho