Поскольку вы обмениваетесь данными без проверки (возможно, для повышения производительности), Oracle не будет проверять, соответствует ли значение для столбца ключа раздела вставляемых данных условию диапазона раздела, в который эти данные вставляются.
--partitioned table
create table mytabp(n date)
partition by range(n)
interval(numtodsinterval(1, 'DAY'))
(partition p0 values less than (to_date('20190901','yyyymmdd')));
--nonpartitioned table to hold the data outside partition range
create table temp_mytab(n date);
insert into temp_mytab values(to_date('20191001','yyyymmdd'));
--exchanging without validation
alter table mytabp exchange partition p0 with table temp_mytab without validation;
--Data exists
select count(1) from mytabp;--1
Из-за сокращения раздела в приведенном ниже запросе запись ищется в разделе, который должен содержать эти данные по определению. Поскольку запись существует в неверном разделе, данные не возвращаются.
select count(1) from mytabp where n > to_date('20190901','yyyymmdd');--0
При применении TRUNC к многораздельному столбцу Oracle получает возможность сканировать все разделы. Таким образом, приведенный ниже SQL создает запись. Для меня в Oracle 12cR1 в Exadata последующие выполнения этого SQL с TRUNC сканировали точный раздел, в котором находилась запись, и не сканировали все разделы. Я проверил это с помощью столбцов PARTITON_START и PARTITION_STOP моего плана объяснения.
select count(1) from mytabp where trunc(n) > to_date('20190901','yyyymmdd');--1
По своей структуре плохо размещать данные на неправильных разделах. Пожалуйста, подтвердите или отфильтруйте правильные данные перед выполнением обмена без проверки.