2009-05-06 11 views
20

J'utilise Oracle DB pour gérer plus de 30 tables, comment puis-je supprimer toutes les données de toutes les tables? Je veux seulement supprimer les données mais ne pas laisser tomber les tables. Clonez le schéma, puis supprimez les anciennes tables?SQL: supprimer toutes les données de toutes les tables disponibles

+0

Cette question semble être hors-sujet car elle appartient sur dba.stackexchange.com – EJP

Répondre

25

Générer un script pour tronquer (= supprimer toutes les lignes de) toutes les tables:

select 'truncate table ' || table_name || ';' from user_tables 

et exécuter le script.

+5

J'ai édité cette réponse, désolé mais la chose all_tables était assez dangereuse. –

+1

solution très soignée, merci beaucoup – Lily

+3

Juste pour les débutants: notez que 'truncate' est non-transactionnel, c'est-à-dire qu'il ne peut pas être annulé. –

2

+0

+1: La solution la plus simple de loin –

+1

Ou la façon «réelle DBA» de le faire: sauvegarder la DB complète sans le d ata, puis reconstruit la base de données (... le serveur ... de la carte mère dessus;). – BCS

+1

@TomH. Comment est-ce simple? Je ne suis pas un DBA, et cela ne me donne aucune idée des commandes à exécuter. –

4

L'inconvénient potentiel d'un tronqué est qu'il peut échouer sur les contraintes d'intégrité référentielle. Donc, vous voudrez d'abord désactiver les contraintes de clé étrangère, puis faites le tronquer, puis réactivez les contraintes. Le 'plus' avec le clonage du schéma (exp et imp) est que vous pouvez aussi supprimer et recréer l'espace de table (ce que vous voudrez peut-être faire si vous voulez récupérer de l'espace disque physique suite à la suppression de toutes les données) .

18

Pour répondre à la question des contraintes, quelque chose comme cela devrait fonctionner:

BEGIN 

    FOR T in (SELECT table_name FROM user_tables) LOOP 
     EXECUTE IMMEDIATE 'ALTER TABLE '||T.table_name||' DISABLE ALL CONSTRAINTS'; 
    END LOOP; 

    FOR T in (SELECT table_name FROM user_tables) LOOP 
     EXECUTE IMMEDIATE 'TRUNCATE TABLE '||T.table_name; 
    END LOOP; 

    FOR T in (SELECT table_name FROM user_tables) LOOP 
     EXECUTE IMMEDIATE 'ALTER TABLE '||T.table_name||' ENABLE ALL CONSTRAINTS'; 
    END LOOP; 
END; 
+1

'alter table ...désactiver toutes les contraintes lance une option ORA-01735: ALTER TABLE invalide si aucune contrainte n'est définie pour la table, ce qui empêcherait le script de tronquer chaque table * s'il y a au moins une table sans contrainte. Vous pouvez placer 'execute immediate' dans un bloc' begin .. exception'. –

30

Il n'y a pas de commande ALTER TABLE XXX DESACTIVEZ CONTRAINTES '

Je propose cela;

BEGIN 
    FOR c IN (SELECT table_name, constraint_name FROM user_constraints WHERE constraint_type = 'R') 
    LOOP 
    EXECUTE IMMEDIATE ('alter table ' || c.table_name || ' disable constraint ' || c.constraint_name); 
    END LOOP; 
    FOR c IN (SELECT table_name FROM user_tables) 
    LOOP 
    EXECUTE IMMEDIATE ('truncate table ' || c.table_name); 
    END LOOP; 
    FOR c IN (SELECT table_name, constraint_name FROM user_constraints WHERE constraint_type = 'R') 
    LOOP 
    EXECUTE IMMEDIATE ('alter table ' || c.table_name || ' enable constraint ' || c.constraint_name); 
    END LOOP; 
END; 
+2

cette solution n'est probablement pas la plus votée car les gens n'aiment pas lire toutes les réponses ici. –

-3

ces scripts deux lignes sont les meilleurs

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL' 
GO 

EXEC sp_MSForEachTable 'DELETE FROM ?' 
GO 
+2

C'est le moyen le plus simple de tronquer toutes les tables d'une base de données Microsoft SQL Server. Même si vous avez oublié de réactiver les contraintes après la suppression des données. Mais ... cette question concerne Oracle ... pas SQL Server. – K4timini

0

Supprimer toutes les données de toutes les tables dans Oracle

DECLARE 
    str VARCHAR2(100); 
BEGIN 
    FOR i IN 
    (SELECT object_name FROM user_objects WHERE object_type='TABLE' 
) 
    LOOP 
    str := 'Truncate table '|| i.object_name; 
    EXECUTE IMMEDIATE str; 
    DBMS_OUTPUT.PUT_LINE('table data deleted :' || i.object_name); 
    END LOOP; 
END;

Pour plus d'informations: http://www.oracleinformation.com/2014/10/delete-all-the-data-from-all-tables.html

1

J'ai créé ce stocké proc, en utilisant les réponses mentionnées ci-dessus. Cela fonctionne parfaitement sans aucune erreur ou exception.

create or replace PROCEDURE DELETE_ALL_DATA 
AS 
cursor r1 is select * from user_constraints; 
cursor r2 is select * from user_tables; 
cursor r3 is select * from user_constraints; 
cursor r4 is select * from user_tables; 

BEGIN 

    FOR c1 IN r1 
    loop 
    for c2 in r2 
    loop 
     begin 
     if c1.table_name = c2.table_name and c1.status = 'ENABLED' THEN 
     dbms_utility.exec_ddl_statement('alter table ' || c1.owner || '.' || c1.table_name || ' disable constraint ' || c1.constraint_name); 
     end if; 
     EXCEPTION 
     WHEN NO_DATA_FOUND 
      THEN 
      continue; 
     WHEN OTHERS 
      THEN 
      continue; 
      end; 
    end loop; 
    END LOOP; 

    FOR T in (SELECT table_name FROM user_tables) LOOP 
     begin 
     EXECUTE IMMEDIATE 'TRUNCATE TABLE '||T.table_name; 
     EXCEPTION 
     WHEN NO_DATA_FOUND 
      THEN 
      continue; 
     WHEN OTHERS 
      THEN 
      continue; 
      end; 
    END LOOP; 

    FOR c1 IN r3 
    loop 
    for c2 in r4 
    loop 
     begin 
     if c1.table_name = c2.table_name and c1.status = 'DISABLED' THEN 
     dbms_utility.exec_ddl_statement('alter table ' || c1.owner || '.' || c1.table_name || ' enable constraint ' || c1.constraint_name); 
     end if; 
     EXCEPTION 
     WHEN NO_DATA_FOUND 
      THEN 
      continue; 
     WHEN OTHERS 
      THEN 
      continue; 
      end; 
    end loop; 
    END LOOP; 

    commit; 
END DELETE_ALL_DATA; 
0

Une légère variation sur la réponse de Andomar tronquer toutes les tables pour un utilisateur spécifique au lieu de seulement ceux de l'utilisateur actuel:

SELECT 'TRUNCATE TABLE ' || owner || '.' || table_name || ';' FROM all_tables WHERE owner = 'user/schema' 

Remplacer le bit user/schema ci-dessus avec le nom de l'utilisateur/schéma (entre les guillemets) vous êtes intéressé.

Questions connexes