Как увеличить размер столбца с индексом

#sql #database #oracle

Вопрос:

Я хочу увеличить размер моей колонки (NVARCHAR2) с 32 до 64. Но я получаю ошибку:

ORA-30556: для изменяемого столбца определяется либо функциональный, либо растровый индекс соединения.

Я нашел решение, которое я должен удалить индекс, а затем воссоздать его. Но могу ли я сделать это, не делая этого? (Может быть, отключить и включить или что-то в этом роде), потому что мне кажется, что это не имеет никакого смысла, когда я увеличиваю размер столбца вверх.

Но даже когда я пытаюсь сделать это, как я сказал выше, иногда я получаю еще одну ошибку

ORA-02429: не удается удалить индекс, используемый для принудительного использования уникального/первичного ключа

Вы можете зачеркнуть HTML — тег и закрыть тег .

Вот так

Я полагаю, что мне нужно сделать индекс непригодным для использования, а затем удалить его и воссоздать все заново. Но это кажется опасным, Кажется, это не работает, даже если бы я хотел это сделать

Ответ №1:

Но, похоже, это опасно

Не все так опасно.

Первый сценарий — тот, с которым вы сейчас имеете дело (увеличение размера столбца, пока на нем есть функциональный индекс) — должен быть в порядке.

 SQL> create table test (id varchar2(2));

Table created.
 

Функциональный индекс:

 SQL> create index i1test on test (upper(id));

Index created.
 

Изменение размера столбца не сработает (как вы уже знаете):

 SQL> alter table test modify (id varchar2(5));
alter table test modify (id varchar2(5))
                         *
ERROR at line 1:
ORA-30556: either functional or bitmap join index is defined on the column to
be modified
 

Итак, снова удалите индекс / измените таблицу / создайте индекс:

 SQL> drop index i1test;

Index dropped.

SQL> alter table test modify (id varchar2(5));

Table altered.

SQL> create index i1test on test (upper(id));

Index created.

SQL>
 

Это опасно? Я так не думаю. Производительность может снизиться, если в таблице нет индекса. Если таблица огромна, то потребуется время, чтобы воссоздать индекс, но — помимо производительности — я думаю, это нормально.


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

 SQL> create table test (id varchar2(2));

Table created.

SQL> create index i1test on test (upper(id));

Index created.

SQL> alter table test add constraint pk_test primary key (id) using index i1test;
alter table test add constraint pk_test primary key (id) using index i1test
*
ERROR at line 1:
ORA-14196: Specified index cannot be used to enforce the constraint.


SQL>
 

Однако, когда мы находимся в индексе, который используется для обеспечения ограничения первичного ключа, тогда да — это может быть опасно, потому что

  • первичный ключ также обеспечивает уникальность, поэтому — если вы его удалите — кто-то может вставить/обновить таблицу и нарушить уникальность
  • на первичный ключ может ссылаться одно (или несколько) ограничений внешнего ключа. Вы не можете отказаться от ограничения первичного ключа, пока существуют внешние ключи, из-за
     ORA-02273: this unique/primary key is referenced by some foreign keys
     

    поэтому сначала вам придется отказаться от ограничений внешнего ключа (вы не можете просто отключить их), что также позволяет кому-то вводить недопустимые значения в этот/эти столбцы

Поэтому все зависит только от текущей ситуации. Иногда это проще, иногда сложнее, и то, как вы с этим справитесь, зависит от сложности.


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

 SQL> create table test (id varchar2(2));

Table created.

SQL> create index i1test on test (id);

Index created.

SQL> alter table test add constraint pk_test primary key (id) using index i1test;

Table altered.

SQL> alter table test modify (id varchar2(5));

Table altered.

SQL>
 

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

1. Спасибо, кажется, я знаю. Но я не понимаю последней части. Почему это alter table test add constraint pk_test primary key (id) using index i1test; позволяет мне изменять таблицу, даже если выше вы показали, что это невозможно без этой строки?

2. Эта ТАБЛИЦА ИЗМЕНЕНИЙ просто добавляет ограничение первичного ключа в ТЕСТОВУЮ таблицу, а ограничение PK использует индекс, который уже существует в столбце идентификатора. Могло бы быть намного проще, например create table test (id varchar2(2) primary key); , и Oracle создала бы ограничение первичного ключа и (в фоновом режиме) индекс, который будет его поддерживать).