Why won’t Oracle alter the size of a column that is used for sub partitioning

alter-tableoraclepartitioning

I am trying to resize a varchar2 column, when I get an ORA-14265 error:

ORA-14265: data type or length of a table subpartitioning column may not be changed

With Oracle providing the unhelpful:

// *Cause: User issued ALTER TABLE statement attempting to modify
// data type and/or length of a column used to subpartition the
// table named in ALTER TABLE statement, which is illegal

// *Action: Avoid modifying data type and/or length of table
// subpartitioning column(s)

So I get that Oracle doesn't want me to alter the column. I presume the hash used for the subpartition would be broken by this. How do I get around this though?

The only suggestion I have found so far that seems plausible is to rename the existing table, and recreate the original with updated schema, then select the data from into the recreated table.

I don't particularly like this idea, for reasons of effort and likelihood of human error:

  • We have lots of partitions, and behind the scenes I'd have to manually ensure the new table matched up identically, so that supporting maintenance scripts could continue along nicely.
  • Then there is disk space. We keep 9 rolling months of data, and I don't have room to suddenly double up on this one table.

Any suggestions would be much appreciated. I hope I'm just missing something easy. Also, if anyone wants to let me know why oracle can't rearrange the data on disk and create a new subpartition hash automagically that would be great.

Best Answer

The solution is dbms_redefinition package. Basically redefition will move, online, to a new table (called interim table), then move all dependent objets like indexes and last exchange the interim table with the original one.

What you have to do is:

  • Create the interim table withe correct column definition
  • Run redefinition
  • Drop the old table

Use dbms_redefinition in the following way:

-- DETERMINE IF THE ORIGINAL TABLE CAN BE REDEFINED ONLINE
BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE('SCHEMA','YOURTABLE', DBMS_REDEFINITION.CONS_USE_ROWID);   
END;
/

-- BEGIN THE REDEFINITION
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(
UNAME => 'SCHEMA',
ORIG_TABLE => 'YOURTABLE',
INT_TABLE => 'INTERIM_YOURTABLE'
OPTIONS_FLAG => DBMS_REDEFINITION.CONS_USE_ROWID);
END;
/

-- IF THE TABLE HAD DEPENDENCIES (INDEXES ... CONSTRAINTS ... TRIGGERS)
-- THIS WOULD BE THE POINT AT WHICH THEY WOULD HAVE BEEN COPIED
DECLARE 
error_count pls_integer := 0;
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('SCHEMA', 'YOURTABLE', 'INTERIM_YOURTABLE', 
dbms_redefinition.cons_orig_params, TRUE, TRUE, TRUE, FALSE, error_count);
DBMS_OUTPUT.PUT_LINE('errors := ' || TO_CHAR(error_count));
END;
/

-- FINISH THE REDEFINITION
exec DBMS_REDEFINITION.FINISH_REDEF_TABLE('SCHEMA','YOURTABLE','INTERIM_YOURTABLE');

If you run redefinition with SYSTEM user there is no problem. If you want to execute it with a less privileged user you have to trick some privileges in order to get it working. Privileges required are:

  • Execute privilege to DBMS_REDEFINITION
  • Create any table
  • Alter any table
  • Drop any table
  • Lock any table
  • Select any table

Tables with the following characteristics cannot be redefined online:

  • [9.0.1]Tables with no primary keys
  • Tables that have materialized view logs defined on them
  • [9i] Tables that are materialized view container tables and AQ tables
  • [10g] Tables that are replicated in an n-way master configuration can be redefined, but horizontal subsetting (subset of rows in the table), vertical subsetting (subset of columns in the table), and column transformations are not allowed.
  • The overflow table of an IOT table
  • Tables with fine-grained access control (row-level security)
  • Tables with BFILE columns
  • Tables with LONG columns can be redefined online, but those columns must be converted to CLOBS. Also, LONG RAW columns must be converted to BLOBS. Tables with LOB columns are acceptable.
  • Tables in the SYS and SYSTEM schema
  • Temporary tables

Other restrictions:

  • A subset of rows in the table
  • Only simple deterministic expressions, sequences, and SYSDATE can be used when mapping the columns in the interim table to those of the original table. For example, subqueries are not allowed.
  • If new columns are being added with no column mappings, then they must not be declared NOT NULL until the redefinition is complete.
  • There cannot be any referential constraints between the table being redefined and the interim table.
  • Table redefinition cannot be done NOLOGGING.
  • [10g] For materialized view logs and queue tables, online redefinition is restricted to changes in physical properties.
  • You cannot convert a nested table to a VARRAY.