【问题标题】:Truncate table in Oracle getting errorsOracle 中的截断表出现错误
【发布时间】:2011-06-16 06:39:12
【问题描述】:

我遇到的问题是当我在 Oracle 中运行以下命令时,我遇到了错误。

Truncate table mytable;

错误:

ORA-02266: unique/primary keys in table referenced by enabled foreign keys

我发现,这个mytable和其他表有关系。这就是为什么 Truncate 命令无法继续进行的原因。如何使用 Truncate 命令使用 SQL 脚本从 myTable 中删除数据?

【问题讨论】:

    标签: sql oracle plsql


    【解决方案1】:

    您必须将 TRUNCATE 语句交换为 DELETE 语句,速度较慢且已记录,但这是在约束到位时执行此操作的方法。

    DELETE mytablename;
    

    或者您可以找到引用相关表的外键并暂时禁用它们。

    select 'ALTER TABLE '||TABLE_NAME||' DISABLE CONSTRAINT '||CONSTRAINT_NAME||';'
    from user_constraints
    where R_CONSTRAINT_NAME='<pk-of-table>';
    

    其中pk-of-table 是被截断表的主键名称

    运行上述查询的输出。完成后,记得再次启用它们,只需将DISABLE CONSTRAINT更改为ENABLE CONSTRAINT

    【讨论】:

    • 我不能使用Delete语句,因为这个表有超过一百万条记录,如果我使用delete会变慢。
    • 如果它有 100 万条记录,我假设您在截断之前删除了所有链接到它的子记录?
    • 我会按照cyberkiwi的选项禁用约束。这样你就不会放弃约束。看看这篇文章,更详细地了解 truncate psoug.org/reference/truncate.html 的行为
    • eeesh ...我迟到了。如果您要截断模型中的所有表,请将具有外键引用的表截断到该表中。
    • +1 这是一个方便的查询,用于定位所有要禁用的约束。
    【解决方案2】:

    这个页面提供了一个很好的解决方案...

    ORA-02266: unique/primary keys in table referenced by enabled foreign keys

    我在这里复制解决方案:

    • 找到引用的 ENABLED 外键约束并禁用它们。
    • 从表中截断/删除。
    • 使用任何文本编辑器 .. 只需在从查询获得的输出中将禁用更改为启用,然后运行它。

      select 'alter table '||a.owner||'.'||a.table_name||' disable constraint '||a.constraint_name||';'
      from all_constraints a, all_constraints b
      where a.constraint_type = 'R' and a.status='ENABLED'
      and a.r_constraint_name = b.constraint_name
      and a.r_owner  = b.owner
      and b.table_name = upper('YOUR_TABLE');
      

    【讨论】:

      【解决方案3】:

      错误消息告诉您有其他表具有引用您的表的外键约束。

      根据Oracle docs

      您不能截断父表 启用的外键约束。 您必须先禁用约束 截断表格。

      syntax for disabling a foreign key 是:

      ALTER TABLE 表名禁用 CONSTRAINT 约束名称;

      【讨论】:

        【解决方案4】:

        问题:

        Error “ORA-02266: unique/primary keys in table referenced by enabled foreign keys” when trying to truncate a table.
        

        错误信息:

        SQL> truncate table TABLE_NAME;  
        
        truncate table TABLE_NAME
                   *
        ERROR at line 1:
        ORA-02266: unique/primary keys in table referenced by enabled foreign keys
        

        解决方案: -- 查找引用的外键约束。

         SQL> select 'alter table '||a.owner||'.'||a.table_name||' disable constraint '||a.constraint_name||';'
          2  from all_constraints a, all_constraints b
          3  where a.constraint_type = 'R'
          4  and a.r_constraint_name = b.constraint_name
          5  and a.r_owner  = b.owner
          6  and b.table_name = 'TABLE_NAME';
        
            'ALTER TABLE'||A.OWNER||'.'||A.TABLE_NAME||'DISABLE CONSTRAINT'||A.CONSTRAINT_NAME||';'
            ---------------------------------------------------------------------------------------------------------
            alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT disable constraint CONSTRAINT_NAME;    
        alter table SCHEMA_NAME.TABLE_NAME_LOCATION disable constraint CONSTRAINT_NAME;
        

        -- 禁用它们

        alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT disable constraint CONSTRAINT_NAME;
        alter table SCHEMA_NAME.TABLE_NAME_LOCATION disable constraint CONSTRAINT_NAME;
        

        -- 运行截断

        SQL> truncate table TABLE_NAME;
        
        Table truncated.
        

        -- 启用外键返回

         SQL> select 'alter table '||a.owner||'.'||a.table_name||' enable constraint '||a.constraint_name||';'
          2  from all_constraints a, all_constraints b
          3  where a.constraint_type = 'R'
          4  and a.r_constraint_name = b.constraint_name
          5  and a.r_owner  = b.owner
          6  and b.table_name = 'TABLE_NAME';
        
        'ALTER TABLE'||A.OWNER||'.'||A.TABLE_NAME||'ENABLE CONSTRAINT'||A.CONSTRAINT_NAME||';'
        --------------------------------------------------------------------------------
        
        alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT enable constraint CONSTRAINT_NAME;
        alter table SCHEMA_NAME.TABLE_NAME_LOCATION enable constraint CONSTRAINT_NAME;
        

        -- 启用它们

        alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT enable constraint CONSTRAINT_NAME;
        alter table SCHEMA_NAME.TABLE_NAME_LOCATION enable constraint CONSTRAINT_NAME;
        

        【讨论】:

          【解决方案5】:

          Oracle 12c introduced a feature 截断作为具有 ON DELETE 规则的参照完整性约束的父级的表。

          而不是truncate table tablename; 使用:

          TRUNCATE TABLE tablename CASCADE;
          

          来自 Oracle truncate table 文档:

          如果您指定 CASCADE,则 Oracle 数据库将截断所有引用具有启用的 ON DELETE CASCADE 引用约束的表的子表。这是一个递归操作,将使用指定的选项截断所有子表、孙表等。

          【讨论】:

            【解决方案6】:

            删除多行有很多约束的典型做法如下:

            • 创建mytable_new,包含所有列但没有约束(或禁用创建约束);
            • 将您需要的任何数据从mytable 复制到mytable_new
            • mytable_new 上启用约束以查看一切正常。
            • 将引用 mytable 的任何约束更改为引用 mytable_new 并查看一切正常。
            • drop table mytable
            • alter table mytable_new rename to mytable

            这比删除具有许多缓慢约束的一百万条记录要快得多。

            【讨论】:

              【解决方案7】:

              我遇到了类似的问题,我通过以下脚本对其进行了整理。

              begin
              for i in (select constraint_name, table_name from user_constraints a where a.owner='OWNER' and a.table_name not in
              (select b.table_name from user_constraints b where b.table_name like '%BIN%') 
                and  a.constraint_type not in 'P')
              LOOP
                execute immediate 'alter table '||i.table_name||' disable constraint '||i.constraint_name||'';
              end loop;
              end;
              /
              
              truncate table TABLE_1;
              truncate table TABLE_2;
              
              
              begin
              for i in (select constraint_name, table_name from user_constraints a where a.owner='OWNER' and a.table_name not in
              (select b.table_name from user_constraints b where b.table_name like '%BIN%') 
                and  a.constraint_type not in 'P')
              LOOP
                execute immediate 'alter table '||i.table_name||' enable constraint '||i.constraint_name||'';
              end loop;
              end;
              /
              

              此脚本将首先禁用所有约束。截断表中的数据,然后启用约束。

              希望对你有帮助。

              干杯..

              【讨论】:

                【解决方案8】:
                TRUNCATE TABLE TEST2 DROP ALL STORAGE;
                

                当 .table 上应用了外键约束时,此语句实际上有效

                【讨论】:

                • 这对我不起作用,除非表格已经是空的。你能创建一个可重现的测试用例吗?
                【解决方案9】:

                如错误消息所述,您不能截断已启用的外键引用的表。如果你真的想使用truncate DDL 命令,首先禁用外键约束,运行 truncate 命令,然后重新启用它。

                参考:Difference between TRUNCATE, DELETE and DROP commands

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2020-09-07
                  • 2013-10-05
                  • 2012-06-10
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多