SQL Создание резервной таблицы с использованием РАЗДЕЛА EXCHANGE

#sql #oracle #backup #partitioning #partition

#sql #Oracle #резервное копирование #разделение #раздел

Вопрос:

Я хочу сделать резервную копию таблицы a1_crm_query с помощью EXCHANGE PARTITION . Эта таблица содержит строки с разными статусами, такими как «ОШИБКА», «НОВЫЙ» или «СДЕЛАНО», и было бы здорово, если бы была еще одна таблица ( a1_crm_query_LOG ) со статусами «ОШИБКА» и «СДЕЛАНО», но моя первая таблица ( a1_crm_query ) будет только с «НОВЫМ».

Прежде всего я создаю свою таблицу:

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

    );
  

Затем я создаю вторую таблицу с разделом.

 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’ в таблицу 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 раздел содержит все строки со всеми статусами.

Ответ №1:

Возможно, вам захочется создать две временные таблицы (temp_error, temp_done) с ОШИБКОЙ и СКОПИРОВАТЬ в них ГОТОВЫЕ данные из таблицы a1_crm_query, затем раздел exchange с таблицами 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 на разделы, то этот подход может подойти вам лучше всего. Вам понадобится одна промежуточная таблица. При таком подходе удаление или усечение не требуется.

 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)
  

Также смотрите эту ссылку

Комментарии:

1. Привет, Акио! Я должен использовать только одну таблицу _log, которая должна содержать оба статуса. Я не могу понять, почему переместить ВСЕ строки, включая «НОВЫЕ»

2. Акио, спасибо, это работает, но в таблице a1_crm_query все еще есть строки с ‘ERROR’ и ‘DONE’. Честно говоря, я не вижу преимуществ этого метода. Я думал, что РАЗДЕЛ EXCHANGE должен заменить операцию ВСТАВКИ- УДАЛЕНИЯ

3. @Jdzel вы можете удалить записи об ОШИБКАХ и выполненных из a1_crm_query. Я опубликую альтернативный подход, если вы также можете разбить a1_crm_query на разделы.

4. Да, будет здорово, если вы опубликуете это. Я могу разбить a1_crm_query на разделы.

5. Акио, спасибо, но после этого обмена я не могу вставить другие строки с этим статусом («ОШИБКА») в a1_crm_query. Я думаю, это происходит из-за перемещения раздела из этой таблицы. Должен ли я добавить раздел в a1_crm_query после обмена?