SQL 使用 EXCHANGE PARTITION 创建备份 table

SQL Creating backup table using EXCHANGE PARTITION

我想使用 EXCHANGE PARTITION 备份 table a1_crm_query。此 table 包含具有不同状态的行,例如 'ERROR'、'NEW' 或 'DONE',如果还有另一个 table(a1_crm_query_LOG) 状态为 'ERROR' 和 'DONE' 但我的第一个 table(a1_crm_query) 将只有 'NEW'.

首先我创建我的table:

 CREATE TABLE ma_user.a1_crm_query (
       ID NUMBER PRIMARY KEY,
       DATA VARCHAR2(200) 

    );

然后我用分区创建第二个 table。

CREATE TABLE ma_user.a1_crm_query_LOG (
       ID NUMBER PRIMARY KEY,
       DATA VARCHAR2(200)
    )
    PARTITION BY LIST (DATA) (
       PARTITION DONE_STATUS VALUES ('DONE'),       
       PARTITION ERROR_STATUS VALUES ('ERROR')
       ) ;

然后将值插入 a1_crm_query:

INSERT INTO ma_user.a1_crm_query SELECT 1 , CAST('NEW' AS VARCHAR2(200)) FROM dual;
INSERT INTO ma_user.a1_crm_query SELECT 2 , CAST('DONE' AS VARCHAR2(200)) FROM dual;
INSERT INTO ma_user.a1_crm_query SELECT 3, CAST('ERROR' AS VARCHAR2(200)) FROM dual; 

现在我想创建日常流程,应该将所有带有 'DONE' 和 'ERROR' 的行移动到 table a1_crm_query_LOGa1_crm_query 应该只'NEW'.

我尝试使用 exchange partition:

    ALTER TABLE ma_user.a1_crm_query_LOG EXCHANGE PARTITION ERROR_STATUS WITH TABLE ma_user.a1_crm_query WITHOUT VALIDATION;
ALTER TABLE ma_user.a1_crm_query_LOG EXCHANGE PARTITION DONE_STATUS WITH TABLE ma_user.a1_crm_query WITHOUT VALIDATION;

但在此之后 ERROR_STATUS 分区包含具有所有状态的所有行。

您可能想要创建两个临时 tables(temp_error、temp_done),其中从 a1_crm_query table 中复制 ERROR 和 DONE 数据], 然后用 table temp_error 和 temp_done.

交换分区

您遇到的问题是因为 WITHOUT VALIDATION。本质上,您是在告诉 Oracle 我已经验证了正在交换的数据,因此 Oracle 不会为您验证它。

this link

更新:方法 1 这就是我要做的。

CREATE TABLE TEMP_ERROR
(       ID NUMBER PRIMARY KEY,
        DATA VARCHAR2(200) );

CREATE TABLE TEMP_DONE 
(
  ID NUMBER PRIMARY KEY,
  DATA VARCHAR2(200) );

insert into TEMP_ERROR
select * from a1_crm_query
where data = 'ERROR';

insert into TEMP_DONE
select * from a1_crm_query
where data = 'DONE';

ALTER TABLE a1_crm_query_LOG EXCHANGE PARTITION ERROR_STATUS WITH TABLE TEMP_ERROR WITHOUT VALIDATION;

ALTER TABLE a1_crm_query_LOG EXCHANGE PARTITION DONE_STATUS WITH TABLE TEMP_DONE WITHOUT VALIDATION;

truncate table temp_error;
truncate table temp_done

更新 2:方法 2 如果您也可以对 a1_crm_query 进行分区,那么这种方法可能最适合您。您将需要一个临时 table。这种方法不需要删除或截断。

CREATE TABLE a1_crm_query (
   ID NUMBER PRIMARY KEY,
   DATA VARCHAR2(200) 

)
    PARTITION BY LIST (DATA) (
   PARTITION DONE_STATUS VALUES ('DONE'),       
   PARTITION ERROR_STATUS VALUES ('ERROR'),
   PARTITION OTHER_STATUS VALUES (DEFAULT)
   ) ;

CREATE TABLE a1_crm_query_LOG (
   ID NUMBER PRIMARY KEY,
   DATA VARCHAR2(200)
)
PARTITION BY LIST (DATA) (
   PARTITION DONE_STATUS VALUES ('DONE'),       
   PARTITION ERROR_STATUS VALUES ('ERROR')
   ) ;


INSERT INTO a1_crm_query SELECT 1 , 'NEW' FROM dual;
INSERT INTO a1_crm_query SELECT 2 , 'DONE'  FROM dual;
INSERT INTO a1_crm_query SELECT 3, 'ERROR' FROM dual; 
commit;       

CREATE TABLE interim
(       ID NUMBER PRIMARY KEY,
       DATA VARCHAR2(200) );



ALTER TABLE a1_crm_query EXCHANGE PARTITION ERROR_STATUS WITH TABLE INTERIM WITHOUT VALIDATION;
ALTER TABLE a1_crm_query_LOG EXCHANGE PARTITION ERROR_STATUS WITH TABLE INTERIM  WITHOUT VALIDATION;

ALTER TABLE a1_crm_query EXCHANGE PARTITION DONE_STATUS WITH TABLE INTERIM WITHOUT VALIDATION;
ALTER TABLE a1_crm_query_LOG EXCHANGE PARTITION DONE_STATUS WITH TABLE INTERIM WITHOUT VALIDATION;

然后您必须在 a1_crm_query

上重建索引
ALTER INDEX <index name> REBUILD;

select * from a1_crm_query;
select * from interim;
select * from a1_crm_query_LOG partition(ERROR_STATUS);
select * from a1_crm_query_LOG partition(done_STATUS)

另见 this link