Решение № 1
Мое решение ниже сохраняет исходный порядок столбцов.
Я обнаружил, что это важно, особенно если есть готовые операторы SQL
есть (средний уровень, клиентский уровень), которые указывают на вашу базу данных, которые неявно
ВЫБИРАЕТ.
т.е.
SELECT *
FROM tableName
WHERE ...;
INSERT INTO copyTableName(column1,column2,column3,...)
SELECT *
FROM tableName
WHERE ...;
Вот так:
Создание DDL для
1. Таблица, содержащая столбец, размер которого вы хотите изменить
2. Все ограничения отношений, индексы, ограничения проверки, триггеры, которые ссылаются на эту таблицу.
3. Все внешние ключи других таблиц, которые ссылаются на первичный ключ этой таблицы.
Убедитесь, что каждый DDL объекта таблицы-ссылки является отдельным, отдельно от
СОЗДАТЬ СТОЛ DDL.
У вас будет что-то вроде
/* 1. The table containing the column you intend to resize */
CREATE TABLE tableName
(
column1 TYPE(size) [DEFAULT value] [NOT] NULL,
column2 TYPE(size) [DEFAULT value] [NOT] NULL,
column3 TYPE(size) [DEFAULT value] [NOT] NULL,
...
)
TABLESPACE tsName
[OPTIONS];
/* 2. All the relationship constraints, indexes, check constraints, triggers that reference that table. */
CREATE INDEX indexName ON tableName
(column1)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
CREATE INDEX compositeIndexName ON tableName
(column1,column2,...)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
CREATE UNIQUE INDEX pkName ON tableName
(column2)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
ALTER TABLE tableName ADD (
CHECK (column4 IS NOT NULL));
ALTER TABLE tableName ADD (
CONSTRAINT pkName
PRIMARY KEY
(column2)
USING INDEX
TABLESPACE INDX);
ALTER TABLE tableName ADD (
CONSTRAINT fkName
FOREIGN KEY (column2)
REFERENCES otherTable (column2));
/* 3. All the foreign keys of other tables that reference the primary key of this table. */
ALTER TABLE otherTableName ADD (
CONSTRAINT otherTableFkName
FOREIGN KEY (otherTableColumn2)
REFERENCES tableName (column1));
Скопируйте только оператор CREATE TABLE
, измените имя таблицы и
уменьшите размер столбца, который вы хотите изменить:
CREATE TABLE tableName_YYYYMMDD
(
column1 TYPE(size) [DEFAULT value] [NOT] NULL,
column2 TYPE(reducedSize) [DEFAULT value] [NOT] NULL,
column3 TYPE(size) [DEFAULT value] [NOT] NULL,
...
)
TABLESPACE tsName
[OPTIONS];
Вставить данные из tableName
в tableName_YYYYMMDD
:
INSERT /* APPEND */ INTO tableName_YYYYMMDD(
column1 ,
column2 ,
column3 ,
... )
SELECT
column1 ,
column2 ,
column3 ,
...
FROM tableName;
COMMIT;
Удалите все объекты, ссылающиеся на исходную таблицу.
Также удалите все внешние ключи, которые ссылаются на первичный ключ tableName pkName.
Не волнуйтесь, вы сохранили DDL, чтобы иметь возможность его воссоздать.
Обратите внимание, что я удаляю индексы после копирования данных из tableName.
Я делаю это, потому что, возможно, один из индексов будет использоваться в
выше ВЫБРАТЬ, чтобы операция завершалась быстрее.
DROP INDEX indexName ;
DROP INDEX compositeIndexName ;
DROP UNIQUE INDEX pkName ;
ALTER TABLE tableName DROP CONSTRAINT pkName ;
ALTER TABLE tableName DROP CONSTRAINT fkName ;
ALTER TABLE otherTableName DROP CONSTRAINT otherTableFkName ;
Оставьте оригинальный стол.
DROP TABLE tableName;
Переименуйте новую таблицу.
ALTER TABLE tableName_YYYYMMDD RENAME TO tableName;
Воссоздайте все ссылочные объекты из операторов DDL, которые вы сохранили ранее.
/* 2. All the relationship constraints, indexes, check constraints, triggers that reference that table. */
CREATE INDEX indexName ON tableName
(column1)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
CREATE INDEX compositeIndexName ON tableName
(column1,column2,...)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
CREATE UNIQUE INDEX pkName ON tableName
(column2)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
ALTER TABLE tableName ADD (
CHECK (column4 IS NOT NULL));
ALTER TABLE tableName ADD (
CONSTRAINT pkName
PRIMARY KEY
(column2)
USING INDEX
TABLESPACE INDX);
ALTER TABLE tableName ADD (
CONSTRAINT fkName
FOREIGN KEY (column2)
REFERENCES otherTable (column2));
/* 3. All the foreign keys of other tables that reference the primary key of this table. */
ALTER TABLE otherTableName ADD (
CONSTRAINT otherTableFkName
FOREIGN KEY (otherTableColumn2)
REFERENCES tableName (column1));
Решение № 2
Сохраняйте порядок столбцов, но не перестраивайте неуникальные используемые PK индексы, которые могут содержать column2.
ALTER TABLE tableName ADD (column2Copy TYPE(reducedSize));
UPDATE tableName SET column2Copy = column2;
ALTER TABLE tableName MODIFY (column2 TYPE(size) NULL);
ALTER TABLE tableName DROP CONSTRAINT pkName;
DROP INDEX pkName;
UPDATE tableName SET column2 = null;
ALTER TABLE tableName MODIFY (column2 TYPE(reducedSize));
UPDATE tableName SET column2 = column2Copy;
ALTER TABLE tableName DROP COLUMN column2Copy;
CREATE UNIQUE INDEX pkName ON tableName
(column2)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
ALTER TABLE tableName ADD (
CONSTRAINT pkName
PRIMARY KEY
(column2)
USING INDEX
TABLESPACE INDX);
COMMIT;