web-dev-qa-db-fra.com

Supprimer tout le contenu d'un schéma dans Oracle

Est-il possible de supprimer tout le contenu du schéma dans Oracle? J'ai trouvé ce script:

Begin
for c in (select table_name from user_tables) loop
execute immediate ('drop table '||c.table_name||' cascade constraints);
end loop;
End;

Mais j'aimerais savoir s'il y a quelque chose à tout supprimer dans le schéma, les index, les tables, les contraintes ... mais pas dans le schéma (utilisateur drop ...).

Merci.

20
zerosssa

Normalement, il est plus simple de supprimer et d'ajouter l'utilisateur. Cette méthode est recommandée si vous avez un accès système ou sysdba à la base de données. 

Si vous n'avez pas accès au niveau système et que vous voulez nettoyer votre schéma, le SQL suivant produira une série d'états de dépôt que vous pourrez ensuite exécuter. 

select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS','') || ';'  from user_objects

Ensuite, je purge normalement la corbeille pour bien nettoyer les choses. Pour être honnête, je ne vois pas beaucoup d'utilisation de la corbeille d'Oracle et j'aimerais pouvoir la désactiver, mais quoi qu'il en soit:

purge recyclebin;

Cela produira une liste d'instructions drop. Tous ne s'exécuteront pas - si vous abandonnez en cascade, supprimer les index PK_ * échouera. Mais à la fin, vous aurez un schéma assez propre. Confirmer avec:

select * from user_objects

De plus, juste pour ajouter, le bloc Pl/sql de votre question ne supprimera que les tables, il ne supprimera pas tous les autres objets.

ps: Copié à partir d'un site Web, m'a été utile. Testé et fonctionnant à merveille.

32
venki

Oui, vous pouvez. Vous pouvez supprimer l'utilisateur, et donc les objets de schéma. L’instruction DROP USER permet de supprimer un utilisateur de la base de données Oracle et de supprimer tous les objets appartenant à cet utilisateur.

DROP USER TestDB;

Cette instruction ne fonctionnera correctement et ne supprimera pas l'utilisateur appelé TestDB que si TestDB ne possède aucun objet dans son schéma. Objet dans les tables et les vues de sens, etc. .. S'il contient des objets, après avoir exécuté l'instruction DROP USER, le message d'erreur ci-dessous s'affiche. 

Error starting at line : 1 in command -
DROP USER TestDB
Error report -
SQL Error: ORA-01922: CASCADE must be specified to drop 'TESTDB'
01922. 00000 -  "CASCADE must be specified to drop '%s'"
*Cause:    Cascade is required to remove this user from the system.  The
           user own's object which will need to be dropped.
*Action:   Specify cascade.

Si TestDB possédait des objets dans son schéma, vous devrez plutôt exécuter l'instruction DROP USER suivante:

DROP USER TestDB CASCADE;

Cette instruction supprimera tous les objets appartenant à TestDB et toutes les contraintes d'intégrité référentielle sur les objets TestDB seront également supprimées.

2
UUIUI

C'est ce que j'ai utilisé:

set echo off feedback off serverout on

spool drop_all_objects.sql

declare  l_object varchar2(32000);

begin

  for i in (select object_name, object_type from dba_objects where owner='<owner>') loop

    if i.object_type='JOB' then

          l_object := 'begin dbms_scheduler.drop_job (job_name => ''<owner>'||i.object_name||'''); end;';

elsif i.object_type='PROGRAM' then

      l_object := 'begin dbms_scheduler.drop_program (program_name => ''<owner>'||i.object_name||'''); end;';

elsif i.object_type='RULE' then

      l_object := 'begin dbms_rule_adm.drop_rule (rule_name => ''<owner>'||i.object_name||''', force => TRUE); end;';

elsif i.object_type='RULE SET' then

      l_object := 'begin dbms_rule_adm.drop_rule_set (rule_set_name => ''<owner>'||i.object_name||''', delete_rules => TRUE); end;';

elsif i.object_type='CHAIN' then

      l_object := 'begin dbms_scheduler.drop_chain (chain_name => ''<owner>'||i.object_name||''', force => TRUE); end;';

elsif i.object_type='RULE' then

      l_object := 'begin dbms_rule_adm.drop_evaluation_context (evaluation_context_name => ''<owner>'||i.object_name||''', force => TRUE); end;';

else

          l_object := 'drop '||i.object_type||'<owner>'||i.object_name||';';

end if;

dbms_output.put_line(i_object);

dbms_output.put_line('/');

end loop;

end;

/

@drop_all_objects
0
John Taylor

Le script SQLplus suivant génère les instructions SQL nécessaires pour supprimer tous les objets de schéma de l'utilisateur souhaité: 

set heading off
set pagesize 0
set feedback off

-- wipe out all scheduler jobs
select 'exec dbms_scheduler.drop_job(job_name => '''||j.job_creator||'.'||j.job_name||''');'
from user_scheduler_jobs j
/

-- wipe out all XML schemas
select 'exec dbms_xmlschema.deleteSchema(schemaURL => '''||s.qual_schema_url||''',delete_option => dbms_xmlschema.DELETE_CASCADE_FORCE);'
from user_xml_schemas s
/

-- wipe out all remaining objects
select 'drop '
       ||o.object_type
       ||' '||object_name
       ||case o.object_type when 'TABLE' then ' cascade constraints' when 'TYPE' then ' force' else '' end
       ||';'
from user_objects o
where o.object_type not in ('JOB','LOB','PACKAGE BODY','INDEX','TRIGGER')
and not exists (select 1
                from user_objects r
                where r.object_name = o.object_name 
                and   r.object_type = 'MATERIALIZED VIEW'
                and   o.object_type != 'MATERIALIZED VIEW'
               )
/

-- empty the recycle bin
select 'purge recyclebin;' from dual
/

Le script fonctionne à 100% pour moi tel quel - mais si, pour une raison quelconque, il n'est pas complet, il est facilement amélioré à l'aide d'une machine virtuelle (VM), comme suit:

  1. connectez-vous en tant que [votre utilisateur de schéma à vider]
  2. Prendre un instantané de votre VM
  3. exécuter le script ci-dessus pour créer les instructions de suppression
  4. exécutez les instructions de suppression (vous pouvez ignorer toutes les erreurs "l'objet n'existe pas", car certains objets seront automatiquement supprimés avant l'instruction de suppression du script. Cela se produit lorsque les objets propriétaires sont supprimés)
  5. se déconnecter
  6. connectez-vous en tant que SYS et exécutez "drop user [votre utilisateur de schéma à vide];" - SANS l'option cascade

Si l'étape 6 échoue, vous devez identifier les objets restants empêchant la suppression de votre utilisateur et les ajouter au script ci-dessus. Répétez l'opération jusqu'à ce que votre utilisateur supprime (votre script soit complet), puis enregistrez votre script.

Rétablissez votre VM sur votre instantané et répétez les étapes 3 et 4 (en utilisant votre script mis à jour) - et vous devriez maintenant avoir un schéma 100% vide.

0
Pancho

Il suffit d'aller avec:

select 'drop '||object_type||' '|| object_name || ';' from user_objects where 
object_type in ('VIEW','PACKAGE','SEQUENCE', 'PROCEDURE', 'FUNCTION', 'INDEX')
0
Tomok