Oracle ORA-08103:更改表时对象不再存在

Oracle ORA-08103:更改表时对象不再存在,oracle,oracle12c,Oracle,Oracle12c,我有一个存储过程,它只启用特定表的约束 它已经工作了很长一段时间,但突然(今天),我得到了ORA-08103错误 这一错误的原因可能是什么 BEGIN FOR c IN ( SELECT c.owner, c.table_name, c.constraint_name FROM user_constraints c WHERE c.status = 'DISABLED' AND c.table_name

我有一个存储过程,它只启用特定表的约束

它已经工作了很长一段时间,但突然(今天),我得到了ORA-08103错误

这一错误的原因可能是什么

  BEGIN
    FOR c IN (
    SELECT
      c.owner,
      c.table_name,
      c.constraint_name
    FROM user_constraints c
    WHERE c.status = 'DISABLED'
          AND c.table_name IN (
      'TABLE_01', 'TABLE_02', 'TABLE_03', 'TABLE_04'
    )) LOOP
      EXECUTE IMMEDIATE 'ALTER TABLE ' || c.table_name || ' ENABLE CONSTRAINT ' || c.constraint_name;
    END LOOP;
  END;
[更新]

  • 禁用约束
  • 加载批量数据
  • 启用约束
这些是我正在遵循的步骤


首先,我禁用表的约束,然后使用SQLLoader加载批量数据,最后启用禁用的约束,在这里我得到ORA-08103错误。

ORA-08103发生在我们尝试对不存在的对象运行DDL语句时。啊,但是你说

他们总是在那里。它们永远不会被丢弃

像表这样的数据库对象在数据字典中有两个标识符,OBJECT_ID和data_OBJECT_ID:我们可以在中看到它们。对象ID在表的生命周期内是恒定的,但数据对象ID(包含对象的段的字典对象号)在对对象执行DDL时会随时更改。例如,当一个表被截断或一个索引被重建时

因此,对于您的情况:ORA-08103错误表明自运行光标以来,数据对象ID已更改。也就是说,当您运行过程时,其他人对其中一个表、约束或基础索引执行了DDL

这可能是一个不幸的巧合,下次运行该过程时不会发生。但是,您可以通过更改运行查询的方式来最大限度地减少再次发生的可能性:

declare
    tabs dbms_debug_vc2coll := dbms_debug_vc2coll ('TABLE_01', 'TABLE_02', 'TABLE_03', 'TABLE_04');
BEGIN
    for idx in 1..tabs.count() loop
        FOR c IN (
            SELECT
                c.owner,
                c.table_name,
                c.constraint_name
            FROM user_constraints c
            WHERE c.table_name = tabs(idx)
            AND c.status = 'DISABLED'
          ) LOOP
             EXECUTE IMMEDIATE 'ALTER TABLE ' || c.table_name || ' ENABLE CONSTRAINT ' || c.constraint_name;
        END LOOP;
    END LOOP;
END;
启用约束需要时间(因为需要验证约束)。因此,逐个选择表可以减少数据对象ID保持固定所需的时间



“上述程序如何最大限度地减少发生相同错误的可能性?”

光标将选择所有四个表,从而选择所有四个数据对象ID。假设在启用表_01上的约束时,另一个会话修改了表_04。当您的过程转到表04时,数据对象ID已更改,您将得到ORA-08103


但是,如果您运行的是我的代码版本,那就无关紧要了,因为在准备好处理它之前,您不会为表04选择数据对象ID。因此,您将获得更改的数据\u对象\u ID(不知道它已更改。

是否有可能这4个表中的一个不再存在?@Rafalon不,它们始终存在。它们将永远不会被删除。那么,其中一个约束条件?是否尝试运行
Select
子句仅检查得到的结果?约束条件也是如此。如果该表不存在错误为“ORA-00942:表或视图不存在”。如果约束不存在,则为“ORA-02430:无法启用约束(XYZ)-无此类约束”.ORA-08103是指内部数据段。您的上述过程如何最大限度地减少相同错误的发生?根据我的观察,我认为这可能与DB规范有关。感谢您提供有用的建议。我已按照您的建议修改了我的过程并运行了它。尽管我确保没有其他人会执行任何类型的操作对于表格,我仍然有同样的错误。如果真的没有其他会话干扰您正在做的事情,那么这一定是您的过程的副作用。唉,对此我无能为力。我已经告诉过您导致错误的原因。现在您必须自己来解决这个问题。从什么开始昨天挂起(或自上次成功运行以来)?如果这没有帮助,请将一些日志记录到过程中,以查看哪些运行,哪些中断。感谢您的建议。我将对此进行深入研究。