Oracle 唯一约束删除和修改
Oracle unique constraint remove and modify
我有一个 table 和 2 个约束——其中一个约束是微不足道的,我想从现有的这个 table——有数据的地方删除它。
下面是table --
create table t1 (aa varchar2(10),bb varchar2(10),cc varchar2(10),dd varchar2(10),ee varchar2(10));
insert into T1 values ('a','b','c','x','y');
insert into T1 values ('d','e','f','u','w');
insert into T1 values ('g','h','i','q','r');
insert into t1 values ('j','k','l','v','z');
alter table T1 add constraint T1_U unique (AA,BB);
alter table T1 add constraint T1_U1 unique (cc,dd);
现在,我们有 2 个约束,我想删除其中的 T1_U1 并修改
T1_U.
2 个约束可以通过--
查看
SELECT * FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');
下面是我正在执行的步骤
禁用T1_U约束--
ALTER TABLE T1 DISABLE CONSTRAINT T1_U;
重命名索引--
ALTER INDEX T1_U1 RENAME TO T1_U;
下降 T1_U.
ALTER TABLE T1 DROP CONSTRAINT T1_U;
现在,如果我检查 USER_OBJECTS
,我仍然可以看到 T1_U
。 -- 为什么会这样?
所以我尝试使用 DROP INDEX T1_U;
-- 这是不正确的。
- 然后我尝试修改
T1_U
-- 如预期的那样失败了。
问题:请问有什么办法可以达到上面的效果吗?
谢谢。
如果你也看看user_constraints:
,这就很容易解释了
create table t1 (aa varchar2(10),bb varchar2(10),cc varchar2(10),dd varchar2(10),ee varchar2(10));
insert into T1 values ('a','b','c','x','y');
insert into T1 values ('d','e','f','u','w');
insert into T1 values ('g','h','i','q','r');
insert into t1 values ('j','k','l','v','z');
alter table T1 add constraint T1_U unique (AA,BB);
alter table T1 add constraint T1_U1 unique (cc,dd);
SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');
OBJECT_NAME OBJECT_TYPE
------------ -------------------
T1_U INDEX
T1_U1 INDEX
select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');
CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME STATUS INDEX_NAME
---------------- --------------- ----------- -------- -----------
T1_U U T1 ENABLED T1_U
T1_U1 U T1 ENABLED T1_U1
存在约束及其相应的索引。
ALTER TABLE T1 DISABLE CONSTRAINT T1_U;
SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');
OBJECT_NAME OBJECT_TYPE
------------ -------------------
T1_U1 INDEX
select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');
CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME STATUS INDEX_NAME
---------------- --------------- ----------- -------- -----------
T1_U1 U T1 ENABLED T1_U1
T1_U U T1 DISABLED
现在禁用约束 T1_U,现在不再需要强制执行索引的索引 T1_U,并且 - 因为 Oracle 知道约束是由约束创建的,而不是单独创建的(我不确定具体如何,但确实如此)- 它知道不再需要该索引,因此可以将其删除。 (可以通过在创建约束之前先创建索引来确认这一点,当禁用约束时,索引仍然存在。)
ALTER INDEX T1_U1 RENAME TO T1_U;
SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');
OBJECT_NAME OBJECT_TYPE
------------ -------------------
T1_U INDEX
select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');
CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME STATUS INDEX_NAME
---------------- --------------- ----------- -------- -----------
T1_U1 U T1 ENABLED T1_U
T1_U U T1 DISABLED
因为没有索引T1_U了,我们可以将T1_U1索引重命名为T1_U。但是请注意,这不会改变它关联的约束 - 它仍然属于 T1_U1 约束。
ALTER TABLE T1 DROP CONSTRAINT T1_U;
SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');
OBJECT_NAME OBJECT_TYPE
------------ -------------------
T1_U INDEX
select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');
CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME STATUS INDEX_NAME
---------------- --------------- ----------- -------- -----------
T1_U1 U T1 ENABLED T1_U
因此,当您删除不再具有关联索引的 T1_U 约束时,只会删除 T1_U 约束。重命名的 T1_U 索引属于 T1_U1 约束,因此,您不会希望它被删除。
此外,如果您现在尝试这样做:
drop index t1_u;
你会得到:
ORA-02429: cannot drop index used for enforcement of unique/primary key
希望这能为您解决第一个问题。
关于你的第二个问题 - "can you please let me know is there any way we can achieve above?" 这完全取决于你想做什么。希望我上面的解释能让你弄清楚你的例子中发生了什么以及为什么,并让你能够回答你自己的问题。
如果没有,请更新您的问题,提供更多关于您要实现的目标的信息。
我有一个 table 和 2 个约束——其中一个约束是微不足道的,我想从现有的这个 table——有数据的地方删除它。
下面是table --
create table t1 (aa varchar2(10),bb varchar2(10),cc varchar2(10),dd varchar2(10),ee varchar2(10));
insert into T1 values ('a','b','c','x','y');
insert into T1 values ('d','e','f','u','w');
insert into T1 values ('g','h','i','q','r');
insert into t1 values ('j','k','l','v','z');
alter table T1 add constraint T1_U unique (AA,BB);
alter table T1 add constraint T1_U1 unique (cc,dd);
现在,我们有 2 个约束,我想删除其中的 T1_U1 并修改 T1_U.
2 个约束可以通过--
查看SELECT * FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');
下面是我正在执行的步骤
禁用T1_U约束--
ALTER TABLE T1 DISABLE CONSTRAINT T1_U;
重命名索引--
ALTER INDEX T1_U1 RENAME TO T1_U;
下降 T1_U.
ALTER TABLE T1 DROP CONSTRAINT T1_U;
现在,如果我检查 USER_OBJECTS
,我仍然可以看到 T1_U
。 -- 为什么会这样?
所以我尝试使用 DROP INDEX T1_U;
-- 这是不正确的。
- 然后我尝试修改
T1_U
-- 如预期的那样失败了。
问题:请问有什么办法可以达到上面的效果吗?
谢谢。
如果你也看看user_constraints:
,这就很容易解释了create table t1 (aa varchar2(10),bb varchar2(10),cc varchar2(10),dd varchar2(10),ee varchar2(10));
insert into T1 values ('a','b','c','x','y');
insert into T1 values ('d','e','f','u','w');
insert into T1 values ('g','h','i','q','r');
insert into t1 values ('j','k','l','v','z');
alter table T1 add constraint T1_U unique (AA,BB);
alter table T1 add constraint T1_U1 unique (cc,dd);
SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');
OBJECT_NAME OBJECT_TYPE
------------ -------------------
T1_U INDEX
T1_U1 INDEX
select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');
CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME STATUS INDEX_NAME
---------------- --------------- ----------- -------- -----------
T1_U U T1 ENABLED T1_U
T1_U1 U T1 ENABLED T1_U1
存在约束及其相应的索引。
ALTER TABLE T1 DISABLE CONSTRAINT T1_U;
SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');
OBJECT_NAME OBJECT_TYPE
------------ -------------------
T1_U1 INDEX
select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');
CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME STATUS INDEX_NAME
---------------- --------------- ----------- -------- -----------
T1_U1 U T1 ENABLED T1_U1
T1_U U T1 DISABLED
现在禁用约束 T1_U,现在不再需要强制执行索引的索引 T1_U,并且 - 因为 Oracle 知道约束是由约束创建的,而不是单独创建的(我不确定具体如何,但确实如此)- 它知道不再需要该索引,因此可以将其删除。 (可以通过在创建约束之前先创建索引来确认这一点,当禁用约束时,索引仍然存在。)
ALTER INDEX T1_U1 RENAME TO T1_U;
SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');
OBJECT_NAME OBJECT_TYPE
------------ -------------------
T1_U INDEX
select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');
CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME STATUS INDEX_NAME
---------------- --------------- ----------- -------- -----------
T1_U1 U T1 ENABLED T1_U
T1_U U T1 DISABLED
因为没有索引T1_U了,我们可以将T1_U1索引重命名为T1_U。但是请注意,这不会改变它关联的约束 - 它仍然属于 T1_U1 约束。
ALTER TABLE T1 DROP CONSTRAINT T1_U;
SELECT object_name, object_type FROM USER_OBJECTS WHERE OBJECT_NAME IN ('T1_U','T1_U1');
OBJECT_NAME OBJECT_TYPE
------------ -------------------
T1_U INDEX
select constraint_name, constraint_type, table_name, status, index_name from user_constraints where constraint_name IN ('T1_U','T1_U1');
CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME STATUS INDEX_NAME
---------------- --------------- ----------- -------- -----------
T1_U1 U T1 ENABLED T1_U
因此,当您删除不再具有关联索引的 T1_U 约束时,只会删除 T1_U 约束。重命名的 T1_U 索引属于 T1_U1 约束,因此,您不会希望它被删除。
此外,如果您现在尝试这样做:
drop index t1_u;
你会得到:
ORA-02429: cannot drop index used for enforcement of unique/primary key
希望这能为您解决第一个问题。
关于你的第二个问题 - "can you please let me know is there any way we can achieve above?" 这完全取决于你想做什么。希望我上面的解释能让你弄清楚你的例子中发生了什么以及为什么,并让你能够回答你自己的问题。
如果没有,请更新您的问题,提供更多关于您要实现的目标的信息。