Как получить имена разделов диапазона дат в таблице между двумя датами (заданный диапазон дат) - PullRequest
0 голосов
/ 26 марта 2020

Я разработчик. В моей таблице были разделы диапазона дат. Я хочу получить имена разделов, которые определены для таблицы между двумя датами. Я попытался с помощью запроса ниже, и он возвращает все разделы в таблице.

select * from USER_TAB_PARTITIONS WHERE TABLE_NAME = 'TABLE NAME' ORDER BY PARTITION_NAME;

Мое требование: я передам две даты в качестве входных данных, и между этими двумя датами я хочу получить имена разделов. Пожалуйста, предложите запрос.

1 Ответ

1 голос
/ 26 марта 2020

Это не очень просто; основным препятствием является user_tab_partitions.high_value тип данных, long, с которым трудно работать. Обычно вы получаете

ORA-00932: несовместимые типы данных: ожидается - получено LONG

ошибка.

Однако, используя несколько шагов, это может быть сделанный. Посмотрите на этот пример.

Создайте секционированную таблицу и вставьте в нее несколько строк:

SQL> CREATE TABLE test_part
  2  (
  3     datum  DATE,
  4     text   VARCHAR2 (10)
  5  )
  6  PARTITION BY RANGE (datum)
  7     INTERVAL ( NUMTODSINTERVAL (1, 'day') )
  8     (PARTITION p0 VALUES LESS THAN (TO_DATE ('01.01.2020', 'dd.mm.yyyy')));

Table created.

SQL> INSERT INTO test_part
  2     SELECT DATE '2015-08-15', 'Little' FROM DUAL
  3     UNION ALL
  4     SELECT DATE '2020-03-26', 'Foot' FROM DUAL;

2 rows created.

Что говорит user_tab_partitions?

SQL> SELECT table_name, partition_name, high_value
  2    FROM user_tab_partitions
  3   WHERE     table_name = 'TEST_PART';

TABLE_NAME      PARTITION_NAME  HIGH_VALUE
--------------- --------------- -----------------------------------
TEST_PART       P0              TO_DATE(' 2020-01-01 00:00:00', 'SY
                                YYY-MM-DD HH24:MI:SS', 'NLS_CALENDA
                                R=GREGORIA

TEST_PART       SYS_P63         TO_DATE(' 2020-03-27 00:00:00', 'SY
                                YYY-MM-DD HH24:MI:SS', 'NLS_CALENDA
                                R=GREGORIA

Итак, Вы хотите извлечь date часть из столбца high_value. Первый шаг довольно глупый - создайте новую таблицу; в основном CTAS:

SQL> CREATE TABLE temp_utp
  2  AS
  3     SELECT table_name, partition_name, TO_LOB (high_value) high_value
  4       FROM user_tab_partitions;

Table created.

Для простоты (в следующих шагах) я создам представление на основе этой таблицы, которое будет извлекать значение date (строка # 5):

SQL> CREATE OR REPLACE VIEW v_utp
  2  AS
  3     SELECT table_name,
  4            partition_name,
  5            TO_DATE (SUBSTR (high_value, 12, 10), 'rrrr-mm-dd') datum
  6       FROM temp_utp;

View created.

Теперь все просто:

SQL> SELECT *
  2    FROM v_utp
  3   WHERE datum < DATE '2020-02-15';

TABLE_NAME      PARTITION_NAME  DATUM
--------------- --------------- ----------
TEST_PART       P0              2020-01-01

SQL>

Хорошо, вы бы использовали два параметра date, которые затем привели бы к between в конечном запросе, но это легко изменить.

Основным недостатком здесь является CTAS, который создает temp_utp таблицу; вам придется воссоздавать его так же часто, как вы добавляете новые разделы в основную таблицу. Один из вариантов - сделать это по расписанию, например, с помощью задания базы данных (см. Документацию dbms_job и / или dbms_scheduler, если вы не знаете, как), чтобы запланировать хранимую процедуру, которая затем будет использовать Dynami c. SQL, т.е. execute immediate для создания temp_utp. Вам не нужно повторно создавать представление - оно станет действительным, как только будет создана новая таблица temp_utp.

...