4

假设,我有下表,

create table SRC_TABLE (
ID NUMBER(2),
NAME VARCHAR(20)
) PARTITION BY LIST (ID)
(
    PARTITION "PART_1" VALUES(1),
    PARTITION "PART_2" VALUES(2)
)

以下是 SRC_TABLE 中的记录

ID         NAME    
-----  ------- 
1          src1    
1          src11   
1          src111  
2          src2    
2          src22  

和其他临时表,

create table STAGE_TABLE (
ID NUMBER(2),
NAME VARCHAR(20)
)

以下是 STAGE_TABLE 中的记录:

ID     NAME    
-----  ------- 
2      2src22  

在运行以下查询时,

ALTER TABLE "SRC_TABLE" EXCHANGE PARTITION "PART_1" WITH TABLE "STAGE_TABLE" WITHOUT VALIDATION

SRC_TABLE 的数据变为:

ID     NAME    
-----  ------- 
2      2src22  
2      src2    
2      src22 

那么,现在名称 = '2src22' 的记录(由于交换而来自阶段表)保留在 PART_1 或 PART_2 中,因为基于 ID 它应该进入 PART_2?

4

1 回答 1

5

当您使用该WITHOUT VALIDATION子句时,您是在告诉 Oracle:“如果新记录满足分区子句,请不要检查它们,我已确保它们都满足分区方案”。

基本上,您已经在数据库中引入了损坏的数据,并且您已经告诉 Oracle 不要执行任何检查。您故意停用了保护,因此记录自然会出现在错误的分区中:

SQL> select * from src_table partition (part_1);

 ID NAME
--- ------------------------------------------------------------
  2 2src22

如果您将数据放在错误的分区中,我相信您会遇到有趣的错误。某些选择可能会返回不一致/错误的结果。您可能还会遇到不寻常的错误消息。

例如,简单的分区修剪会给出错误的结果(感谢@Alex Poole):

SQL> SELECT * FROM src_table WHERE ID = 1;

 ID NAME
--- ------------------------------------------------------------
  2 2src22

如果您实际使用验证会发生什么:

SQL> ALTER TABLE "SRC_TABLE" EXCHANGE PARTITION "PART_1" WITH TABLE STAGE_TABLE;

ORA-14099: all rows in table do not qualify for specified partition

您会收到一条很好的错误消息,说明您正在尝试做错事。不要试图通过停用保护来解决错误消息。请改正您的数据。

于 2013-09-25T10:09:51.710 回答