最近我在使用DBMS_REDEFINITION
时在一个数据库(12cR1)中发现了一个奇怪的故障模式。 CAN_REDEF_TABLE
可以很好地完成,START_REDEF_TABLE
也可以,但是COPY_TABLE_DEPENDENTS
失败时会产生困惑:
ORA-01741:非法的零长度标识符
经过一些调试后,异常似乎与{strong> {strong> ORIG_TABLE
列中包含和隐式系统名称的INVISIBLE
有关约束。我将在下面提供一个示例来演示该问题,但我希望对该行为有所了解,并且在docs中未发现关于INVISIBLE
的任何值得注意的内容。
我想更好地理解创建系统生成的约束似乎有些细微差别。为“为什么”问题表示歉意,但是,为什么在重新定义期间隐式系统约束的行为与显式定义的约束有什么不同?我以为,在分配了系统生成的名称后,约束就是约束。系统生成的对象是否在其他方面与客户端命名的约束(其名称之外)不同?
我还希望看看是否还有其他解决方法可以建议,而不仅仅是重命名隐式约束或在重新定义之前取消隐藏列。
谢谢
示例:
以下是用于重新定义的同一ORIG_TABLE
的三个版本。前两个都使用给定的INT_TABLE
进行了远低于标准的重新定义,但是第三个在ORA-01741
期间抛出了COPY_TABLE_DEPENDENTS
。
版本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
);
针对以下内容运行第一个选项将起作用,而在复制后将第三个选项运行失败。
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;
/
答案 0 :(得分:1)
似乎是由于oracle的错误。该错误已在oracle 12.2上修复。 以下是一些关键信息:
错误17871192:ILM策略在列不可见的桌子上出现ORA-01741失败
添加了不可见的非null默认列的表上的ADO策略失败 并显示以下消息:
ORA-12012:自动执行作业“ SYS”时出错。“ ILMJOB2628” ORA-1741:非法的零长度标识符 ORA-6512:位于“ SYS.DBMS_REDEFINITION”的第2525行
要重现,您需要一个表,该表的列包含以下命令 添加:
在表“ ILMT3”中添加“ C4” varchar2(10)不可见默认值''不为null;
必须复制所有三个属性。
不要使用其中一个属性
发行说明:
]]缺少看不见的列元数据。
重新发现信息:
在“看不见的列”中缺少列名,则您遇到了这个问题。
答案 1 :(得分:1)
首先,您不需要将NOT NULL
与PRIMARY KEY
子句一起使用。摆脱 such NOT NULL
s。
让我们在您的情况下,在 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
和 DB版本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.
因此,结果紧随其后:
ORA-042067
,而不是ORA-01741
。因此,需要为INVISIBLE
表的THE_DATE (DATE)
列添加REDEFINER
选项,以实现original
和interim
表之间的真实列映射。INVISIBLE
选项,您也会
对于版本 R1 ,仍然获得相同的错误代码(ORA-01741
),而
您将成功获得版本 R2 。因此,升级似乎是
REDEFINER
表时
需要删除 R1 的视图,但不删除 R2 的视图。有趣,可能是一个错误...