Ao testar alguns scripts de migração com uma cópia dos dados de produção (os scripts funcionam bem com os dados de desenvolvimento), encontrei uma situação curiosa. A CONSTRAINT mudou, então estou emitindo comandos DROP + ADD:
ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT A_DUP_CALLE_UK1;
ALTER TABLE A_DUP_CALLE
ADD CONSTRAINT A_DUP_CALLE_UK1 UNIQUE (
CONTROL_ID,
CALLE_AYTO_DUPL
)
ENABLE;
O comando DROP funcionou bem, mas o ADD falhou. Agora, estou em um círculo vicioso. Não consigo descartar a restrição porque ela não existe (o descarte inicial funcionou conforme o esperado):
ORA-02443: Não é possível descartar restrição - restrição inexistente
E não consigo criá-lo porque o nome já existe:
ORA-00955: nome já é usado por um objeto existente
Eu digito na caixa de pesquisaA_DUP_CALLE_UK1
do SQL Developer e... aí está! Owner, nome da tabela, tablescape... tudo combina: não é um objeto diferente com o mesmo nome, é minha restrição original. A tabela aparece nos detalhes da restrição, mas a restrição não aparece nos detalhes da tabela.
Minhas perguntas:
- Qual é a explicação para isso?
- Como posso garantir que isso não acontecerá quando eu fizer a atualização real no servidor ativo?
(O servidor é 10g XE, não tenho reputação suficiente para criar a tag.)
Em um palpite, eu diria que Marian está certa e isso é causado por um índice e restrição exclusivos com o mesmo nome, por exemplo:
Normalmente, quando você adiciona uma restrição exclusiva, um índice exclusivo com o mesmo nome é criado - mas o índice e a restrição não são a mesma coisa. Dê uma olhada
all_indexes
para ver se há um índice chamadoA_DUP_CALLE_UK1
e tente descobrir se ele é usado por outra coisa antes de soltá-lo!Parece muito estranho.
Você pode correr:
para verificar se o tipo de objeto que o Oracle reclama. Então você pode executar a instrução DROP apropriada para isso.
A única outra coisa em que consigo pensar é descartar a tabela inteiramente usando
DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTS
para se livrar de tudo o que pertence a essa tabela e depois recriá-la completamente.Se a tabela contiver dados valiosos, você poderá fazer um backup dela antes:
Depois de recriar a tabela, você pode fazer
para restaurar os dados.
Eu tive o mesmo problema há apenas alguns minutos... e encontrei uma explicação.
Ao criar uma Chave Primária, o Oracle cria dois objetos: uma restrição e um índice, que controla a parte "UNIQUE".
Ao descartar a restrição, o índice permanece lá, usando o mesmo nome do índice, portanto, se você executar apenas
Você estará descartando apenas a restrição. Para eliminar o índice, você precisará executar
Isso deve fazer o trabalho. Alternativamente, você pode fazer esses dois comandos ao mesmo tempo com o comando
A restrição de chave primária vem com index. Você descarta a restrição, mas não o índice. Verificar:
e você vê
OBJECT_TYPE
éINDEX
.Então faça os dois:
Fazem isto
Vai funcionar.
IMAGEM: