Boa tarde comunidade,
Tenho um script PLSQL executado no ORACLE 19 que está exibindo um erro que não entendo.
O script descarta qualquer índice existente antes de recriá-los. Os objetos são definidos em uma lista de tipo-off para evitar repetição de instruções
- remover um índice inexistente está OK (basta capturar a exceção e continuar)
- criar um índice que está falhando deve continuar a criar os índices restantes até o fim
Meu script PLSQL é
set serveroutput on;
WHENEVER SQLERROR EXIT SQL.SQLCODE;
DECLARE
index_not_exists EXCEPTION;
table_not_exists EXCEPTION;
PRAGMA EXCEPTION_INIT (index_not_exists, -1418);
PRAGMA EXCEPTION_INIT (table_not_exists, -942);
TYPE ind_list IS TABLE OF VARCHAR(100) NOT NULL;
ind_to_drop ind_list := ind_list('sst_ind1', 'sst_ind2');
/* first index is wrong because col0 does not exist */
ind_to_create ind_list := ind_list('create index sst_ind1 on sst_table(col0)', 'create index sst_ind2 on sst_table(col2)');
sql_to_exec varchar(200);
is_all_index_created boolean := TRUE;
BEGIN
BEGIN
EXECUTE IMMEDIATE 'drop table sst_table cascade constraints purge';
EXCEPTION
WHEN table_not_exists THEN
NULL;
END;
EXECUTE IMMEDIATE 'create table sst_table (col1 number, col2 number)';
EXECUTE IMMEDIATE 'create index sst_ind1 on sst_table (col1)';
EXECUTE IMMEDIATE 'create index sst_ind2 on sst_table (col2)';
FOR l_index IN ind_to_drop.FIRST..ind_to_drop.LAST LOOP
BEGIN
sql_to_exec := 'drop index ' || ind_to_drop(l_index);
dbms_output.put_line(sql_to_exec);
EXECUTE IMMEDIATE sql_to_exec;
EXCEPTION
WHEN index_not_exists THEN
dbms_output.put_line('no index ' || ind_to_drop(l_index));
END;
END LOOP;
FOR l_index IN ind_to_create.FIRST..ind_to_create.LAST LOOP
BEGIN
dbms_output.put_line(ind_to_create(l_index));
EXECUTE IMMEDIATE ind_to_create(l_index);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('ERROR WITH ' || ind_to_create(l_index));
is_all_index_created := FALSE;
END;
END LOOP;
IF NOT is_all_index_created THEN
RAISE_APPLICATION_ERROR(-20001, 'PROBLEM CREATING INDEX');
END IF;
END;
/
exit
Quando executo meu script pelo sqplus tenho o ERRO abaixo não entendi
sqlplus xxxxx/yyyyy@zzzzzz @ubscls_6711.sql
SQL*Plus: Release 11.2.0.4.0 Production on Wed Sep 25 17:04:11 2024
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
drop index sst_ind1
drop index sst_ind2
create index sst_ind1 on sst_table(col0)
ERROR WITH create index sst_ind1 on sst_table(col0)
create index sst_ind2 on sst_table(col2)
DECLARE
*
ERROR at line 1:
ORA-20001: PROBLEM CREATING INDEX
ORA-06512: at line 49
Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Alguém pode me ajudar a consertar meu problema? Provavelmente é simples, mas não consigo encontrar o motivo.
Obrigado
Ele está fazendo o que você disse que deveria... sua pergunta afirma que:
Há um comentário no código que diz:
A saída mostra:
... para que a criação do índice falhe como esperado (escondendo o erro real, o que não ajuda, como @Koen disse); então ele continua e mostra:
... que aparentemente tem sucesso. Então ele continuou a criar os índices restantes.
Você está usando o sinalizador
is_all_index_created
para manter o controle de quaisquer problemas. Isso está sendo definido como falso pela falha esperada. Então, no final do seu código, você tem:e esse é o erro que você está vendo:
Você está recebendo um erro porque seu código diz para gerar esse erro, então não há nada a corrigir, já que você quer/espera que a primeira criação de índice falhe.
No início do script você tem
então seu script sairá com o código -20001, indicando uma falha, em vez de zero, indicando sucesso. Você pode não ver -20001, no entanto, ele pode ser modificado para um intervalo menor; scripts Unix-y se envolvem se o código de saída estiver fora do intervalo permitido, então você pode ver -33 ou 233, por exemplo. (O que é um motivo para evitar usar isso, pois alguns códigos de erro reais se envolveriam em zero e pareceriam sucesso... é mais seguro
... EXIT FAILURE
)O script manipula quaisquer exceções que são levantadas, mas não mostra qual é o erro. Dê uma olhada neste bloco no script.
O que ele faz é: se ocorrer qualquer tipo de erro, então imprima na tela que ... há um erro.
Isso não é muito útil. Há algumas funções internas para lhe dar mais informações.
SQLERRM
fornece o código de erro e a descrição do erro,SQLCODE
mostrará apenas o código de erro,dbms_utility.format_error_backtrace
mostra a pilha completa.Para o seu caso,
SQLERRM
provavelmente deve ser o suficiente.