ORA-01741 for DBMS_REDEFINITION 具有不可见字段和隐式约束

ORA-01741 for DBMS_REDEFINITION with invisible fields and implicit constraints

我最近注意到一个数据库 (12cR1) 在使用 DBMS_REDEFINITION 时出现了一种奇怪的故障模式。 CAN_REDEF_TABLE 完成得很好,START_REDEF_TABLE 也是如此,但是 COPY_TABLE_DEPENDENTS 失败并令人困惑:

ORA-01741: illegal zero-length identifier

经过一些调试,异常似乎与 ORIG_TABLE 携带 both INVISIBLEand 隐式系统命名约束。我将在下面包含一个示例来说明问题,但我希望对行为有一些了解,并且没有看到 docs 中调用的 INVISIBLE 有任何值得注意的地方。

我想更好地理解系统生成的约束的创建似乎有些细微差别。对 "why" 问题表示歉意,但是,为什么隐式系统约束在重新定义期间的行为与显式定义的约束有任何不同?我原以为在分配了一个系统生成的名称后,约束就只是一个约束。系统生成的对象是否在其他方面不同于其名称之外的客户端命名约束?

我还希望看看除了重命名隐式约束或在重新定义之前取消隐藏列之外,是否有人可以推荐其他解决方法。

谢谢

示例: 下面是同一个ORIG_TABLE的三个版本重新定义。前两个都使用给定的 INT_TABLE 进行远低于重新定义,但第三个在 COPY_TABLE_DEPENDENTS 期间抛出 ORA-01741

版本 1:所有列可见,系统生成的隐式约束:

CREATE TABLE REDEF_TARGET (
  THE_KEY  INTEGER NOT NULL PRIMARY KEY ,
  THE_DATE DATE    NOT NULL
);

版本 2:存在 INVISIBLE 列,显式约束(如果 DBMS_REDEFINITION 正在检测现有名称,请在此处给出一个荒谬的名称)

CREATE TABLE REDEF_TARGET (
  THE_KEY  INTEGER NOT NULL PRIMARY KEY ,
  THE_DATE DATE INVISIBLE ,
  CONSTRAINT SYS_C02583271 CHECK (THE_DATE IS NOT NULL)
);

版本 3:INVISIBLE 列和隐式约束都存在

CREATE TABLE REDEF_TARGET (
  THE_KEY  INTEGER NOT NULL PRIMARY KEY ,
  THE_DATE DATE INVISIBLE NOT NULL
);

运行 下面的第一个将起作用,而第三个将在 copy-deps 期间失败。

CREATE TABLE REDEFINER (
  THE_KEY  INTEGER ,
  THE_DATE DATE
);

DECLARE
  V_NUM INTEGER;
BEGIN
  DBMS_REDEFINITION.CAN_REDEF_TABLE(UNAME => USER , TNAME => 'REDEF_TARGET');
  DBMS_REDEFINITION.START_REDEF_TABLE(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER');
  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER' , NUM_ERRORS => V_NUM);
  DBMS_REDEFINITION.FINISH_REDEF_TABLE(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER');
END;
/

似乎是由于 oracle bug.the 错误已在 oracle 12.2 上修复。 以下是一些关键信息:

错误 17871192:ILM 策略失败,ORA-01741 ON TABLE WITH INVISIBLE COLUMN

问题:

添加了不可见非空默认列的 table 上的 ADO 策略失败 带有以下消息:

ORA-12012: 自动执行作业时出错 "SYS"。"ILMJOB2628" ORA-1741: 非法的零长度标识符 ORA-6512:在 "SYS.DBMS_REDEFINITION",第 2525 行

诊断分析:

要重现,您需要一个 table,其中有一列包含以下命令 已添加:

alter table "ILMT3" add "C4" varchar2 (10) invisible default ' ' not null;

需要全部三个属性才能重现。

解决方法:

不要使用其中一个属性

发行说明:

]] INVISIBLE COLUMN 元数据丢失。

重新发现信息:

在 INVISIBLE COLUMN 中缺少列名,那么您遇到了这个问题。

首先你不需要使用 NOT NULL with PRIMARY KEY 子句。去掉suchNOT NULLs.

让我们 运行 您对 DB 版本 12cR1 的版本 3 的声明,就您的情况而言:

Connected to Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 
Connected as hr

SQL> CREATE TABLE REDEF_TARGET (
  2    THE_KEY  INTEGER PRIMARY KEY ,
  3    THE_DATE DATE INVISIBLE NOT NULL
  4  );

Table created

SQL> CREATE TABLE REDEFINER(
  2    THE_KEY  INTEGER,
  3    THE_DATE DATE
  4  );

Table created

SQL> DECLARE
  2    V_NUM INTEGER;
  3  BEGIN
  4    DBMS_REDEFINITION.CAN_REDEF_TABLE(UNAME => USER , TNAME => 'REDEF_TARGET');
  5    DBMS_REDEFINITION.START_REDEF_TABLE(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER');
  6    DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER' , NUM_ERRORS => V_NUM);
  7    DBMS_REDEFINITION.FINISH_REDEF_TABLE(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER');
  8  END;
  9  /

ORA-01741: illegal zero-length identifier
ORA-06512: at "SYS.DBMS_REDEFINITION", line 1646
ORA-06512: at "SYS.DBMS_REDEFINITION", line 2502
ORA-06512: at "SYS.DBMS_REDEFINITION", line 3803
ORA-06512: at line 7

SQL> DROP TABLE REDEF_TARGET;

Table dropped

SQL> DROP TABLE REDEFINER;

DROP TABLE REDEFINER

ORA-12083: must use DROP MATERIALIZED VIEW to drop "HR"."REDEFINER"

SQL> DROP MATERIALIZED VIEW REDEFINER;

Materialized view dropped

SQL> DROP TABLE REDEFINER;

Table dropped

SQL> CREATE TABLE REDEF_TARGET (
  2    THE_KEY  INTEGER PRIMARY KEY ,
  3    THE_DATE DATE INVISIBLE NOT NULL
  4  );

Table created

SQL> CREATE TABLE REDEFINER(
  2    THE_KEY  INTEGER,
  3    THE_DATE DATE INVISIBLE
  4  );

Table created

SQL> DECLARE
  2    V_NUM INTEGER;
  3  BEGIN
  4    DBMS_REDEFINITION.CAN_REDEF_TABLE(UNAME => USER , TNAME => 'REDEF_TARGET');
  5    DBMS_REDEFINITION.START_REDEF_TABLE(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER');
  6    DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER' , NUM_ERRORS => V_NUM);
  7    DBMS_REDEFINITION.FINISH_REDEF_TABLE(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER');
  8  END;
  9  /

ORA-01741: illegal zero-length identifier
ORA-06512: at "SYS.DBMS_REDEFINITION", line 1646
ORA-06512: at "SYS.DBMS_REDEFINITION", line 2502
ORA-06512: at "SYS.DBMS_REDEFINITION", line 3803
ORA-06512: at line 7

数据库版本 12cR2 :

Connected to Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 
Connected as hr

SQL> CREATE TABLE REDEF_TARGET (
  2    THE_KEY  INTEGER PRIMARY KEY ,
  3    THE_DATE DATE INVISIBLE NOT NULL
  4  );

Table created

SQL> CREATE TABLE REDEFINER(
  2    THE_KEY  INTEGER,
  3    THE_DATE DATE
  4  );

Table created

SQL> DECLARE
  2    V_NUM INTEGER;
  3  BEGIN
  4    DBMS_REDEFINITION.CAN_REDEF_TABLE(UNAME => USER , TNAME => 'REDEF_TARGET');
  5    DBMS_REDEFINITION.START_REDEF_TABLE(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER');
  6    DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER' , NUM_ERRORS => V_NUM);
  7    DBMS_REDEFINITION.FINISH_REDEF_TABLE(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER');
  8  END;
  9  /

ORA-042067: invalid column mapping with invisible columns on original or interim table
ORA-06512: at "SYS.DBMS_REDEFINITION", line 109
ORA-06512: at "SYS.DBMS_REDEFINITION", line 3887
ORA-06512: at "SYS.DBMS_REDEFINITION", line 5208
ORA-06512: at line 5

SQL> DROP TABLE REDEF_TARGET;

Table dropped

SQL> DROP TABLE REDEFINER;

Table dropped

SQL> CREATE TABLE REDEF_TARGET (
  2    THE_KEY  INTEGER PRIMARY KEY ,
  3    THE_DATE DATE INVISIBLE NOT NULL
  4  );

Table created

SQL> CREATE TABLE REDEFINER(
  2    THE_KEY  INTEGER,
  3    THE_DATE DATE INVISIBLE
  4  );

Table created

SQL> DECLARE
  2    V_NUM INTEGER;
  3  BEGIN
  4    DBMS_REDEFINITION.CAN_REDEF_TABLE(UNAME => USER , TNAME => 'REDEF_TARGET');
  5    DBMS_REDEFINITION.START_REDEF_TABLE(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER');
  6    DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER' , NUM_ERRORS => V_NUM);
  7    DBMS_REDEFINITION.FINISH_REDEF_TABLE(UNAME => USER , ORIG_TABLE => 'REDEF_TARGET' , INT_TABLE => 'REDEFINER');
  8  END;
  9  /

PL/SQL procedure successfully completed.

所以,结果如下

  • Version 12c Release 1 抑制了主要问题 ORA-042067 而不是 ORA-01741。因此,需要为 REDEFINER table 的 THE_DATE (DATE) 列添加 INVISIBLE 选项,以实现 originalinterim [=57= 之间的真实列映射]s.
  • 即使为上述列添加了 INVISIBLE 选项,您也会 对于版本 R1,仍然得到相同的错误代码 (ORA-01741),而 您将在 R2 版本中获得成功。所以,升级似乎是 必要的。
  • 顺便说一下,每次我们尝试下降 REDEFINER table,物化 R1 需要删除视图,但 R2 不需要删除视图。有趣,可能是一个错误...