Registros duplicados - Unique Constraint Violated ORA-00001

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
vasilva
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 24
Registrado em: Qua, 28 Out 2009 9:58 am
Localização: RS

Bom dia pessoal !!!

Por gentileza, preciso de um help para a seguinte questão:

Tenho um processo que "expurga" uma base principal para outra base de expurgo, esta base de expurgo recebe os registros "velhos".
Bem, durante o processo ele pega os registros da base principal e tenta inserir na base de expurgo e em determinada tabela me apresentou o seguinte erro:

Selecionar tudo

"ORA-00001: unique constraint (BASE_EXPURGO.UK_COLUNA_LOGIN) violated
ORA-06512: at "BASE_EXPURGO.SP_COPY_7951F1CE_103", line 39
ORA-06512: at line 1"
Creio que tenha havido o erro pelo fato de o registro já existir na tabela de destino e por isso não permitiu a inserção, havendo violação de constraint.
Como faço para validar com base nesta constraint de há registros duplicados na tabela destino ? Tem um SELECT para isto ?

Abaixo a procedure que faz o update ou insert:

Selecionar tudo

CREATE OR REPLACE PROCEDURE SP_COPY_7951F1CE_103
(
  pNEW_FD_COLUNA1 varchar2, 
  pNEW_FD_COLUNA2 varchar2, 
  pNEW_FD_COLUNA3 varchar2, 
  pNEW_FD_COLUNA4 varchar2, 
  pNEW_FD_COLUNA5 date, 
  pNEW_FD_COLUNA6 varchar2, 
  pNEW_FD_COLUNA7 date, 
  pNEW_FD_COLUNA8 varchar2, 
  pNEW_FD_COLUNA9 varchar2, 
  pNEW_FD_COLUNA10 Number, 
  pNEW_FD_COLUNA11 Number, 
  pNEW_FD_COLUNA12 varchar2, 
  pNEW_FD_COLUNA13 Number
) IS 

BEGIN

  UPDATE TB_ACC_HOLDERS SET FD_COLUNA1 = pNEW_FD_COLUNA1, 
                            FD_COLUNA2 = pNEW_FD_COLUNA2, 
                            FD_COLUNA3 = pNEW_FD_COLUNA3, 
                            FD_COLUNA4 = pNEW_FD_COLUNA4, 
                            FD_COLUNA5 = pNEW_FD_COLUNA5, 
                            FD_COLUNA6 = pNEW_FD_COLUNA6, 
                            FD_COLUNA7 = pNEW_FD_COLUNA7, 
                            FD_COLUNA8 = pNEW_FD_COLUNA8, 
                            FD_COLUNA9 = pNEW_FD_COLUNA9, 
                            FD_COLUNA10 = pNEW_FD_COLUNA10, 
                            FD_COLUNA11 = pNEW_FD_COLUNA11, 
                            FD_COLUNA12 = pNEW_FD_COLUNA12, 
                            FD_COLUNA13 = pNEW_FD_COLUNA13
         WHERE FD_COLUNA13 = pNEW_FD_COLUNA13;



  IF SQL%RowCount = 0 THEN

     INSERT INTO TB_TABELA1
                 ( FD_COLUNA1, FD_COLUNA2, FD_COLUNA3, FD_COLUNA4, FD_COLUNA5, FD_COLUNA6, 
                   FD_COLUNA7, FD_COLUNA8, FD_COLUNA9, FD_COLUNA10, FD_COLUNA11, FD_COLUNA12, FD_COLUNA13)
            VALUES
                 ( pNEW_FD_COLUNA1, pNEW_FD_COLUNA2, pNEW_FD_COLUNA3, pNEW_FD_COLUNA4, pNEW_FD_COLUNA5, 
                 pNEW_FD_COLUNA6, pNEW_FD_COLUNA7, pNEW_FD_COLUNA8, pNEW_FD_COLUNA9, pNEW_FD_COLUNA10,
                 pNEW_FD_COLUNA11, pNEW_FD_COLUNA12, pNEW_FD_COLUNA13,);
  END IF;
END;


Desde já agradeço!
VaSilva
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Se a linha já está do outro lado, você pode fazer duas coisas:

Usar o comando MERGE,

ou então no comando insert tratar a exception: WHEN_DUP_VAL_ON_INDEX

abraço
vasilva
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 24
Registrado em: Qua, 28 Out 2009 9:58 am
Localização: RS

Olá Diego !

Por favor, tu podes me mostrar um exemplo deste "MERGE" ?


Obrigado!
VaSilva
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Ele é um comando pra INSERT e UPDATE,

No caso a regra que você deve atentar-se é na linha
ON ( n1.empno = e1.empno )

pois é onde "diz" que os registros são os mesmos entre as tabelas, nesse caso é como se fosse a constraint que esta sendo violada, ai você deve relacionar as duas tabelas, e aí com base nisso, caso MATCHED, seria o ORA00001, então faz UPDATE pois o registro já existe, caso NOT MATCHED você faz o insert, o registro ainda não está lá,
a idéia é essa, espero ter ajudado.

Selecionar tudo

MERGE INTO newemp  n1
USING external_table e1
  ON ( n1.empno = e1.empno  )
  WHEN MATCHED THEN UPDATE
      SET -- n1.empno   = e1.empno,
           n1.ename    = e1.ename,
           n1.job      = e1.job,
           n1.mgr      = e1.mgr,
           n1.hiredate = e1.hiredate,
           n1.sal      = e1.sal,
           n1.comm     = e1.comm,
           n1.deptno   = e1.deptno
  WHEN NOT MATCHED THEN
  INSERT ( empno, ename, job, mgr, hiredate, sal, comm, deptno )
  values ( e1.empno,
           e1.ename,
           e1.job,
           e1.mgr,
           e1.hiredate,
           e1.sal,
           e1.comm,
           e1.deptno )
vasilva
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 24
Registrado em: Qua, 28 Out 2009 9:58 am
Localização: RS

Entendido Diego !!
Mas neste momento, o que preciso é mesmo fazer um "select" após executado o processo, preciso apenas de um "select" onde eu consiga comparar de há registros duplicados com base na constraint, pra rodar na mão mesmo.

Obrigado.
VaSilva
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Veja quais são os campos que essa constraint usa para validar, e coloca no where, acho que é +- por ai

Selecionar tudo

select * 
  from tabela1
 where (campo1, campo2) in (select campo1, campo2 from tabela2)
vasilva
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 24
Registrado em: Qua, 28 Out 2009 9:58 am
Localização: RS

Diego, consegui validar duplicidade com a seguinte query:

Selecionar tudo

SELECT FD_COLUNA1, COUNT(*)
 FROM TB_TABELA
 GROUP BY FD_COLUNA1
 HAVING COUNT(*) > 1
:P


Obrigado pela ajuda e atenção.
Abraços!
VaSilva
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Achava que você queria validar tabelas diferentes, blza

parabens
vasilva
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 24
Registrado em: Qua, 28 Out 2009 9:58 am
Localização: RS

Me desculpe, acho que me expressei mal.

Muito obrigado meu caro !

Ps: Tu monitora o forum pra saber quando há um novo tópico ?
Eu gostaria de participar e responder também as dúvidas, não só perguntar.


Abraço.
VaSilva
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Vai em Indice do Forum,

http://glufke.net/oracle/index.php?sid= ... e5ef5221ba

No canto superior direito tem um link "Ultimos 10 Posts",

marque no seu perfil pra receber por email quando for feito um post você receber, caso você já tenha particapado postando algo, vai receber na sequencia sempre uma notificacao
Responder
  • Informação
  • Quem está online

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