【问题标题】:How do I delete the data from all my tables in ORACLE 10g如何从 ORACLE 10g 中的所有表中删除数据
【发布时间】:2010-02-17 12:14:54
【问题描述】:

我有一个包含数百个表的 ORACLE 架构。我想从所有表中删除数据(但不想删除表)。

有没有一种简单的方法可以做到这一点,还是我必须编写一个 SQL 脚本来检索所有表名并在每个表上运行 TRUNCATE 命令?

我想在 SQL-Plus 会话中使用命令删除数据。

【问题讨论】:

    标签: oracle10g


    【解决方案1】:

    如果您有任何参照完整性约束(外键),那么 truncate 将不起作用;如果存在任何子表,则不能截断父表,即使子表为空。

    以下 PL/SQL 应该(它未经测试,但我过去曾运行过类似的代码)遍历表,禁用所有外键,截断它们,然后重新启用所有外键。如果另一个模式中的表对您的表有 RI 约束,则此脚本将失败。

    set serveroutput on size unlimited
    declare
      l_sql       varchar2(2000);
      l_debug     number          := 1;  -- will output results if non-zero
                                         -- will execute sql if 0
      l_drop_user varchar2(30)    := ''  -- set the user whose tables you're dropping
    begin
      for i in (select table_name, constraint_name from dba_constraints
                 where owner = l_drop_user
                   and constraint_type = 'R'
                   and status = 'ENABLED')
      loop
        l_sql := 'alter table ' || l_drop_user || '.' || i.table_name || 
                 ' disable constraint ' || i.constraint_name;
        if l_debug = 0 then
          execute immediate l_sql;
        else
          dbms_output.put_line(l_sql);
        end if;
      end loop;
    
      for i in (select table_name from dba_tables
                 where owner = l_drop_user
                minus
                select view_name  from dba_views
                 where owner = l_drop_user)
      loop
        l_sql := 'truncate table ' || l_drop_user || '.' || i.table_name ;
        if l_debug = 0 then
          execute immediate l_sql;
        else
          dbms_output.put_line(l_sql);
        end if;
      end loop;
    
      for i in (select table_name, constraint_name from dba_constraints
                 where owner = l_drop_user
                   and constraint_type = 'R'
                   and status = 'DISABLED')
      loop
        l_sql := 'alter table ' || l_drop_user || '.' || i.table_name || 
                 ' enable constraint ' || i.constraint_name;
        if l_debug = 0 then
          execute immediate l_sql;
        else
          dbms_output.put_line(l_sql);
        end if;
      end loop;
    end;
    /
    

    【讨论】:

    • 它被正确执行但它不起作用!数据仍在所有表中。
    • 你能展示一下这个之前和之后吗?因为这是我半定期使用的代码。
    【解决方案2】:

    可能最简单的方法是在没有数据的情况下导出架构,然后删除重新导入它。

    【讨论】:

    • 不仅是最简单的方法,而且如果这些表中有任何数量的数据,那么这也是最快的方法。
    【解决方案3】:

    我也在看这个。

    似乎您确实需要检查所有表名。

    你见过this吗?似乎可以解决问题。

    【讨论】:

      【解决方案4】:

      我最近不得不这样做并编写了一个存储过程,您可以通过以下方式运行它:exec sp_truncate;。大部分代码都基于此:answer on disabling constraint

          CREATE OR REPLACE PROCEDURE sp_truncate AS 
      BEGIN
        -- Disable all constraints
        FOR c IN
        (SELECT c.owner, c.table_name, c.constraint_name
         FROM user_constraints c, user_tables t
         WHERE c.table_name = t.table_name
         AND c.status = 'ENABLED'
         ORDER BY c.constraint_type DESC)
        LOOP
          DBMS_UTILITY.EXEC_DDL_STATEMENT('ALTER TABLE ' || c.owner || '.' || c.table_name || ' disable constraint ' || c.constraint_name);
          DBMS_OUTPUT.PUT_LINE('Disabled constraints for table ' || c.table_name);
        END LOOP;
      
        -- Truncate data in all tables
         FOR i IN (SELECT table_name FROM user_tables)
         LOOP
            EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || i.table_name;
            DBMS_OUTPUT.PUT_LINE('Truncated table ' || i.table_name); 
         END LOOP;
      
         -- Enable all constraints
         FOR c IN
           (SELECT c.owner, c.table_name, c.constraint_name
            FROM user_constraints c, user_tables t
            WHERE c.table_name = t.table_name
            AND c.status = 'DISABLED'
            ORDER BY c.constraint_type)
           LOOP
             DBMS_UTILITY.EXEC_DDL_STATEMENT('ALTER TABLE ' || c.owner || '.' || c.table_name || ' enable constraint ' || c.constraint_name);
             DBMS_OUTPUT.PUT_LINE('Enabled constraints for table ' || c.table_name);
           END LOOP;
      
         COMMIT;
      END sp_truncate;
      /
      

      【讨论】:

        【解决方案5】:

        将来自OTN Discussion Forums: truncating multiple tables with single query 线程的详细信息放入一个 SQL 脚本中,可以在 SQL-Plus 会话中运行以下内容:

        SET SERVEROUTPUT ON
        
        BEGIN
            -- Disable constraints
            DBMS_OUTPUT.PUT_LINE ('Disabling constraints');
            FOR reg IN (SELECT uc.table_name, uc.constraint_name FROM user_constraints uc) LOOP
                EXECUTE IMMEDIATE 'ALTER TABLE ' || reg.table_name || ' ' || 'DISABLE' ||
                    ' CONSTRAINT ' || reg.constraint_name || ' CASCADE';
            END LOOP;
        
            -- Truncate tables
            DBMS_OUTPUT.PUT_LINE ('Truncating tables');
            FOR reg IN (SELECT table_name FROM user_tables) LOOP
                EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || reg.table_name;
            END LOOP;
        
            -- Enable constraints
            DBMS_OUTPUT.PUT_LINE ('Enabling constraints');
            FOR reg IN (SELECT uc.table_name, uc.constraint_name FROM user_constraints uc) LOOP
                EXECUTE IMMEDIATE 'ALTER TABLE ' || reg.table_name || ' ' || 'ENABLE' ||
                    ' CONSTRAINT ' || reg.constraint_name;
            END LOOP;
        END;
        /
        

        【讨论】:

          猜你喜欢
          • 2015-12-19
          • 2011-03-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-06
          • 1970-01-01
          • 2010-09-10
          • 1970-01-01
          相关资源
          最近更新 更多