Renaming tables in TimesTen

Недавно, на форуме получил вопрос от заказчика - как переименовать таблицу в TimesTen?
Первым делом, как настоящий пацан, я открыл документацию и не обнаружил команды 'alter table rename', следовательно, единственный способ переименовать таблицу - создать таблицу CTAS и после удалить старую.
Небольшой пример:
Command> create table my_all_source as select * from all_source;
7566 rows inserted.
Command> create table my_raname_tab as select * from my_all_source;
7566 rows inserted.
Command> drop table my_all_source;
Command> tables;
  ORATT.MY_RANAME_TAB
1 table found.
Command>

Ну это и дети знают. Но что происходит с констрайнтами, индексами при CTAS. Конечно они отсутствуют. Вопрос в том, как переименовать таблицу, и потом восстановить все констрэйнты и индексы.

Предположим у нас есть таблицы:

Command> create table tab1 (id number not null primary key, sum number);
Command> create table tab2 (id number not null primary key, name varchar2(50));
Command> create table tab_for_rename (id_1 number not null primary key, id_tab1 number, id_tab2 number);
Command> create table tab3 (id number not null primary key, id_tab_for_rename number);
Command> create table tab4 (id number not null primary key, id_tab_for_rename number);
Command> tables;
  ORATT.TAB1
  ORATT.TAB2
  ORATT.TAB3
  ORATT.TAB4
  ORATT.TAB_FOR_RENAME
5 tables found.
Command>

Необходимо переименовать таблицу tab_for_rename. Предположим, что в данной таблице существует первичный ключ, и несколько внешних ключей. Кроме того, предположим, что существуют таблицы (которые мы не знаем), которые ссылаются на первичный ключ tab_for_rename.

Command> ALTER TABLE tab_for_rename ADD FOREIGN KEY (id_tab1) REFERENCES tab1 (id);
Command> ALTER TABLE tab_for_rename ADD FOREIGN KEY (id_tab2) REFERENCES tab2 (id);
Command> ALTER TABLE tab3 ADD FOREIGN KEY (id_tab_for_rename) REFERENCES tab_for_rename (id_1);
Command> ALTER TABLE tab4 ADD FOREIGN KEY (id_tab_for_rename) REFERENCES tab_for_rename (id_1);
Command>

Заполним таблицы данными:

Command> insert into tab1 (id, sum) select rownum, rownum from all_source;
7566 rows inserted.
Command> insert into tab2 (id, name) select rownum, to_char(rownum) from all_source;
7566 rows inserted.
Command> insert into tab_for_rename (id_1, id_tab1, id_tab2) select rownum, rownum,rownum from all_source;
7566 rows inserted.
Command> insert into tab3 select rownum, rownum from all_source;
7566 rows inserted.
Command> insert into tab4 select rownum, rownum from all_source;
7566 rows inserted.
Command>

Вначале, создадим таблицу с новым именем.

Command> create table renamed_tab as select * from tab_for_rename;
7566 rows inserted.
Command> indexes renamed_tab;

Indexes on table ORATT.RENAMED_TAB:
  No indexes found.

0 indexes found on 1 table.
Command>

Теперь необходимо создать все констрэйнты и индексы.
Command> indexes TAB_FOR_RENAME;

Indexes on table ORATT.TAB_FOR_RENAME:
  TAB_FOR_RENAME: unique T-tree index on columns:
    ID_1
    (referenced by foreign key index TTFOREIGN_20 on table ORATT.TAB3)
    (referenced by foreign key index TTFOREIGN_21 on table ORATT.TAB4)
  TTFOREIGN_18: non-unique T-tree index on columns:
    ID_TAB1
    (foreign key index references table ORATT.TAB1(ID))
  TTFOREIGN_19: non-unique T-tree index on columns:
    ID_TAB2
    (foreign key index references table ORATT.TAB2(ID))
  3 indexes found.

3 indexes found on 1 table.
Command>

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

Пересоздадим их.

Command> ALTER TABLE renamed_tab ADD constraint new_pk Primary key (id_1);
Command> ALTER TABLE renamed_tab ADD FOREIGN KEY (id_tab1) REFERENCES tab1 (id);
Command> ALTER TABLE renamed_tab ADD FOREIGN KEY (id_tab2) REFERENCES tab2 (id);
Command> ALTER TABLE tab3 ADD FOREIGN KEY (id_tab_for_rename) REFERENCES renamed_tab (id_1);
Command> ALTER TABLE tab4 ADD FOREIGN KEY (id_tab_for_rename) REFERENCES renamed_tab (id_1);
Command>

После этого, наблюдаем удвоение индексов у таблиц tab1, tab2,tab3,tab4.

Command> indexes;

Indexes on table ORATT.RENAMED_TAB:
  NEW_PK: unique T-tree index on columns:
    ID_1
    (referenced by foreign key index TTFOREIGN_24 on table ORATT.TAB3)
    (referenced by foreign key index TTFOREIGN_25 on table ORATT.TAB4)
  TTFOREIGN_22: non-unique T-tree index on columns:
    ID_TAB1
    (foreign key index references table ORATT.TAB1(ID))
  TTFOREIGN_23: non-unique T-tree index on columns:
    ID_TAB2
    (foreign key index references table ORATT.TAB2(ID))
  3 indexes found.

Indexes on table ORATT.TAB1:
  TAB1: unique T-tree index on columns:
    ID
    (referenced by foreign key index TTFOREIGN_22 on table ORATT.RENAMED_TAB)
    (referenced by foreign key index TTFOREIGN_18 on table ORATT.TAB_FOR_RENAME)
  1 index found.

Indexes on table ORATT.TAB2:
  TAB2: unique T-tree index on columns:
    ID
    (referenced by foreign key index TTFOREIGN_23 on table ORATT.RENAMED_TAB)
    (referenced by foreign key index TTFOREIGN_19 on table ORATT.TAB_FOR_RENAME)
  1 index found.

Indexes on table ORATT.TAB3:
  TAB3: unique T-tree index on columns:
    ID
  TTFOREIGN_20: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.TAB_FOR_RENAME(ID_1))
  TTFOREIGN_24: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.RENAMED_TAB(ID_1))
  3 indexes found.

Indexes on table ORATT.TAB4:
  TAB4: unique T-tree index on columns:
    ID
  TTFOREIGN_21: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.TAB_FOR_RENAME(ID_1))
  TTFOREIGN_25: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.RENAMED_TAB(ID_1))
  3 indexes found.

Indexes on table ORATT.TAB_FOR_RENAME:
  TAB_FOR_RENAME: unique T-tree index on columns:
    ID_1
    (referenced by foreign key index TTFOREIGN_20 on table ORATT.TAB3)
    (referenced by foreign key index TTFOREIGN_21 on table ORATT.TAB4)
  TTFOREIGN_18: non-unique T-tree index on columns:
    ID_TAB1
    (foreign key index references table ORATT.TAB1(ID))
  TTFOREIGN_19: non-unique T-tree index on columns:
    ID_TAB2
    (foreign key index references table ORATT.TAB2(ID))
  3 indexes found.

14 indexes found on 6 tables.
Command>

Теперь удалим старую таблицу.

Command> ALTER TABLE tab3 DROP CONSTRAINT TTFOREIGN_20;
Command> ALTER TABLE tab4 DROP CONSTRAINT TTFOREIGN_21;
Command> drop table TAB_FOR_RENAME;
Command> indexes;

Indexes on table ORATT.RENAMED_TAB:
  NEW_PK: unique T-tree index on columns:
    ID_1
    (referenced by foreign key index TTFOREIGN_24 on table ORATT.TAB3)
    (referenced by foreign key index TTFOREIGN_25 on table ORATT.TAB4)
  TTFOREIGN_22: non-unique T-tree index on columns:
    ID_TAB1
    (foreign key index references table ORATT.TAB1(ID))
  TTFOREIGN_23: non-unique T-tree index on columns:
    ID_TAB2
    (foreign key index references table ORATT.TAB2(ID))
  3 indexes found.

Indexes on table ORATT.TAB1:
  TAB1: unique T-tree index on columns:
    ID
    (referenced by foreign key index TTFOREIGN_22 on table ORATT.RENAMED_TAB)
  1 index found.

Indexes on table ORATT.TAB2:
  TAB2: unique T-tree index on columns:
    ID
    (referenced by foreign key index TTFOREIGN_23 on table ORATT.RENAMED_TAB)
  1 index found.

Indexes on table ORATT.TAB3:
  TAB3: unique T-tree index on columns:
    ID
  TTFOREIGN_24: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.RENAMED_TAB(ID_1))
  2 indexes found.

Indexes on table ORATT.TAB4:
  TAB4: unique T-tree index on columns:
    ID
  TTFOREIGN_25: non-unique T-tree index on columns:
    ID_TAB_FOR_RENAME
    (foreign key index references table ORATT.RENAMED_TAB(ID_1))
  2 indexes found.

9 indexes found on 5 tables.
Command>

Следовательно, переименовать таблицу в TimesTen не составляет большого труда, даже с учетом отсутствия команды 'alter table rename'. Правда, есть нюанс, т.к. новая таблица создается как CTAS, то в вашей базе данных должно быть достаточно места для хранения копии данных и индексов, поэтому данный метод применим не всегда.

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