我使用的是 Oracle 19c 数据库。我有一些限制,我想获得 DDL。通常它看起来像这样:
ALTER TABLE "MY_OWNER"."MY_TABLE1" ADD CONSTRAINT "MY_CONSTRAINT1" UNIQUE ("NAME", "ID")
USING INDEX PCTFREE ...
注意它没有显式创建一个新的命名索引。
但是,对于某些约束(不确定有什么区别),它显式创建索引,如下所示:
ALTER TABLE "MY_OWNER"."MY_TABLE2" ADD CONSTRAINT "MY_CONSTRAINT2" UNIQUE ("NAME", "ID")
USING INDEX (CREATE UNIQUE INDEX "MY_OWNER"."MY_INDEX2" ON "MY_OWNER"."MY_TABLE2" ("NAME", "ID") ...
我已经在创建索引,因此当我尝试运行它时,这会导致
ORA-00955: name is already used by an existing object
错误。
第二种情况的约束有什么不同?如何让 DDL 不创建唯一索引?
PK/UK 约束索引可以单独预先创建,也可以由约束本身隐式创建。
如果预先创建,当添加约束时,它只是“采用”索引,但会记住它是单独创建的。当您禁用或删除约束时,它不会对索引执行任何操作,索引被视为单独的对象。这通常用于利用能够创建并行索引的性能优势,这是约束 DDL 不可能实现的。
如果在添加约束时隐式创建索引,则它以更紧密的方式拥有索引,这样禁用或删除约束将自动删除基础索引。所以这更简单,但是您不能使用并行性来构建索引。
事实是,我们生活在一个会遇到这两种情况的世界,是的,这有点令人头疼。您可以通过检查
dba_indexes.constraint_index = 'YES'
来判断是哪种情况。
然而,对于
dbms_metadata
,有一个已知的问题。它不一致,我在自己的模式复制代码中遇到了同样的事情。我在代码中嵌入了以下代码片段:
/*
** dbms_metadata incorrectly generates the wrong DDL for auto-generated constraint indexes and can create several variations of the USING INDEX clause. Standardize by remove the USING INDEX clause entirely.
*/
var_ddls(i).ddltext := REGEXP_REPLACE(var_ddls(i).ddltext,'USING INDEX.*(ENABLE|DISABLE)','\1',1,0,'n');
所以看来我必须从 DDL 中对其进行字符串操作,这可能意味着我无法找到解决问题的转换。