Как изменить выражение виртуального столбца по которому секционирована таблица? Ошибка: ORA-54019

Есть таблица, которая секционирована по виртуальному столбцу, требуется изменить выражение для этого виртуального столбца, но, по-видимому, это невозможно сделать тем способом, который пробую:

ALTER TABLE MY_TABLE
MODIFY VIRTUAL_COLUMN 
GENERATED ALWAYS AS (TO_DATE(SUBSTR(SOME_COLUMN, 4, 8), 'yyyymmdd'))

ORA-54019: Невозможно изменить выражение виртуального столбца, т.к. этот столбец является столбцом секционирования

Как можно изменить этот виртуальный столбец?


Свободный перевод вопроса HHow to solve ORA-54019: Virtual column expression cannot be changed because it is a partitioning column? от участника @Dinu Nicolae


Ответы (1 шт):

Автор решения: 0xdb

Если виртуальный столбец является частью ключа секционирования, то его выражением нельзя изменить.

Если требуется его изменить так, чтобы можно было также изменить схему секционирования, то надо:

  • Добавить новый виртуальный столбец с нужным выражением.
  • Изменить схему секционирования, чтобы использовать новый виртуальный столбец.

Если версия 18c или выше, то можно сделать с ALTER TABLE:

create table t (d date, v number as (to_number (to_char (d, 'yyyymmdd' )))) 
    partition by range (v) (
        partition p0 values less than (20200101))
/
alter table t
  modify v number as (to_number (to_char (d, 'yyyymm')))
/
ORA-54019: Невозможно изменить выражение виртуального столбца, 
           т.к. этот столбец является столбцом секционирования
54019. 0000 -  "Virtual column expression cannot be changed because it is a partitioning column"
*Cause:    Attempted to modify the expression of a virtual column that was
           also a partitioning column.
*Action:   This is not supported.

alter table t
  add v2 number as (to_number (to_char (d, 'yyyymm')))
/ 
alter table t
    modify partition by range (v2) (
        partition p0 values less than (202001)
    ) online
/
select column_name 
from user_part_key_columnswhere name = 'T';

COLUMN_NAME
----------------
V2

Для более старых версий лучше использовать пакет DBMS_REDEFINITION, чтобы минимизировать время простоя. Например, как показано в этой статье.


Свободный перевод ответа от участника @Chris Saxon

→ Ссылка