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_LOG
,a1_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 不会为您验证它。
更新:方法 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
我想使用 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_LOG
,a1_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 不会为您验证它。
更新:方法 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