#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 создала бы ограничение первичного ключа и (в фоновом режиме) индекс, который будет его поддерживать).