Le moyen le plus efficace et le plus efficace consiste à intercepter l'exception "table non trouvée": cela évite la surcharge de vérification si la table existe deux fois; et ne souffre pas du problème que si le DROP échoue pour une autre raison (qui pourrait être importante), l'exception est toujours levée à l'appelant:
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
ADDENDUM
Pour référence, voici les blocs équivalents pour les autres types d'objets:
Séquence
BEGIN
EXECUTE IMMEDIATE 'DROP SEQUENCE ' || sequence_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2289 THEN
RAISE;
END IF;
END;
Vue
BEGIN
EXECUTE IMMEDIATE 'DROP VIEW ' || view_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
Déclencheur
BEGIN
EXECUTE IMMEDIATE 'DROP TRIGGER ' || trigger_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4080 THEN
RAISE;
END IF;
END;
Indice
BEGIN
EXECUTE IMMEDIATE 'DROP INDEX ' || index_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1418 THEN
RAISE;
END IF;
END;
Colonne
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE ' || table_name
|| ' DROP COLUMN ' || column_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -904 AND SQLCODE != -942 THEN
RAISE;
END IF;
END;
Lien de base de données
BEGIN
EXECUTE IMMEDIATE 'DROP DATABASE LINK ' || dblink_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2024 THEN
RAISE;
END IF;
END;
Vue matérialisée
BEGIN
EXECUTE IMMEDIATE 'DROP MATERIALIZED VIEW ' || mview_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -12003 THEN
RAISE;
END IF;
END;
Type
BEGIN
EXECUTE IMMEDIATE 'DROP TYPE ' || type_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Contrainte
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE ' || table_name
|| ' DROP CONSTRAINT ' || constraint_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2443 AND SQLCODE != -942 THEN
RAISE;
END IF;
END;
Travail du planificateur
BEGIN
DBMS_SCHEDULER.drop_job(job_name);
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -27475 THEN
RAISE;
END IF;
END;
Utilisateur / Schéma
BEGIN
EXECUTE IMMEDIATE 'DROP USER ' || user_name;
/* you may or may not want to add CASCADE */
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1918 THEN
RAISE;
END IF;
END;
Paquet
BEGIN
EXECUTE IMMEDIATE 'DROP PACKAGE ' || package_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Procédure
BEGIN
EXECUTE IMMEDIATE 'DROP PROCEDURE ' || procedure_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Fonction
BEGIN
EXECUTE IMMEDIATE 'DROP FUNCTION ' || function_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Espace disque logique
BEGIN
EXECUTE IMMEDIATE 'DROP TABLESPACE' || tablespace_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -959 THEN
RAISE;
END IF;
END;
Synonyme
BEGIN
EXECUTE IMMEDIATE 'DROP SYNONYM ' || synonym_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1434 THEN
RAISE;
END IF;
END;
EXECUTE IMMEDIATE 'DROP TABLE mytable';
phrases (une pour chaque table du script), dois-je mettre un gestionnaire d'exceptions pour chacune, ou est-ce suffisant pour encapsuler toutes les senteces dans unBEGIN ... EXCEPTION ... END;
bloc?IF OBJECT_ID('TblName') IS NOT NULL DROP TABLE TblName
. Il semble que la verbosité d'un langage SQL soit proportionnelle au prix.C'est pour vérifier si une table dans le schéma actuel existe. Pour vérifier si une table donnée existe déjà dans un schéma différent, vous devez utiliser à la
all_tables
place deuser_tables
et ajouter la conditionall_tables.owner = upper('schema_name')
la source
Je cherchais la même chose mais j'ai fini par écrire une procédure pour m'aider:
J'espère que cela t'aides
la source
Je voulais juste publier un code complet qui va créer un tableau et le déposer s'il existe déjà en utilisant le code de Jeffrey (bravo à lui, pas moi!).
la source
Avec SQL * PLUS, vous pouvez également utiliser la commande WHENEVER SQLERROR:
Une
CONTINUE NONE
erreur est signalée, mais le script continuera. AvecEXIT SQL.SQLCODE
le script sera terminé en cas d'erreur.voir aussi: WHENEVER SQLERROR Docs
la source
Il n'y a pas de 'DROP TABLE IF EXISTS' dans oracle, vous devriez faire l'instruction select.
essayez ceci (je ne suis pas sur la syntaxe Oracle, donc si mes variables sont ify, veuillez me pardonner):
la source
Je préfère suivre la solution économique
la source
Une autre méthode consiste à définir une exception, puis à intercepter uniquement cette exception en laissant tous les autres se propager.
la source
Une façon consiste à utiliser DBMS_ASSERT.SQL_OBJECT_NAME :
DBFiddle Demo
la source
Malheureusement non, il n'y a rien de tel que drop s'il existe, ou CRÉER SI N'EXISTE PAS
Vous pouvez écrire un script plsql pour y inclure la logique.
http://download.oracle.com/docs/cd/B12037_01/server.101/b10759/statements_9003.htm
Je ne suis pas beaucoup dans la syntaxe Oracle, mais je pense que le script de @ Erich serait quelque chose comme ça.
la source
Vous pouvez toujours détecter l'erreur vous-même.
Il est considéré comme une mauvaise pratique d'en abuser, comme pour les catch () vides dans d'autres langues.
Cordialement
K
la source
Je préfère spécifier la table et le propriétaire du schéma.
Faites également attention à la sensibilité à la casse. (voir la clause "supérieure" ci-dessous).
J'ai jeté un couple d'objets différents pour montrer qu'il peut être utilisé dans des endroits autres que des tables.
.............
Et un exemple de TABLE:
la source
// En faisant ce code, vérifie si la table existe et plus tard, elle crée la table max. cela fonctionne simplement en une seule compilation
la source
Et si vous voulez le rendre réinscriptible et minimiser les cycles de suppression / création, vous pouvez mettre en cache le DDL à l'aide de dbms_metadata.get_ddl et tout recréer à l'aide d'une construction comme celle-ci:
declare v_ddl varchar2(4000); begin select dbms_metadata.get_ddl('TABLE','DEPT','SCOTT') into v_ddl from dual; [COMPARE CACHED DDL AND EXECUTE IF NO MATCH] exception when others then if sqlcode = -31603 then [GET AND EXECUTE CACHED DDL] else raise; end if; end;
ceci n'est qu'un exemple, il devrait y avoir une boucle à l'intérieur avec Le type, le nom et le propriétaire DDL étant des variables.la source
Un bloc comme celui-ci pourrait vous être utile.
la source