我最近注意到一个数据库 (12cR1) 在使用 DBMS_REDEFINITION
时出现了一种奇怪的故障模式。 CAN_REDEF_TABLE
完成得很好,START_REDEF_TABLE
也是如此,但是 COPY_TABLE_DEPENDENTS
失败并令人困惑:
ORA-01741: illegal zero-length identifier
经过一些调试,异常似乎与ORIG_TABLE
携带both INVISIBLE
列and 隐式系统命名约束。我将在下面包含一个示例来演示该问题,但我希望对行为有一些了解,并且没有看到关于在 docs 中调用的 INVISIBLE
有任何值得注意的地方 | .
我想更好地理解系统生成的约束的创建似乎有些细微差别。对“为什么”的问题表示歉意,但是,为什么隐式系统约束在重新定义期间的行为与显式定义的约束有任何不同?我原以为在分配了一个系统生成的名称后,约束就只是一个约束。系统生成的对象是否在其他方面不同于其名称之外的客户端命名约束?
除了重命名隐式约束或在重新定义之前取消隐藏列之外,我还希望看看是否有人可以推荐其他解决方法。
谢谢
例子:
下面是相同的 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;
/
最佳答案
首先,您不需要将 NOT NULL
与 PRIMARY KEY
子句一起使用。摆脱这样的 NOT NULL
。
让我们按照您的情况在 DB version 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
表的THE_DATE (DATE)
列添加INVISIBLE
选项,以便在original
之间实现真正的列映射> 和临时
表。 - 即使为上述列添加了
INVISIBLE
选项,您也会 对于版本 R1 仍然得到相同的错误代码 (ORA-01741
),而 R2 版本你会成功的。所以,升级似乎是 必要的。 - 顺便说一句,每次我们尝试删除
REDEFINER
表时,都会具体化 R1 需要删除 View ,R2 则不需要。有趣,可能是一个错误......
关于oracle - ORA-01741 用于带有不可见字段和隐式约束的 DBMS_REDEFINITION,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51391212/