Почему этот столбец Oracle DROP изменяет значение по умолчанию другого столбца?

у нас есть странная ситуация в таблице в базе данных Oracle, где удаление столбца приводит к изменению значений по умолчанию другого столбца. Вот сценарий.

у меня есть таблица с некоторыми образцами данных в ней:

select * from SAMPLE_TABLE ;

ID                                       BUSINESS_KEY
---------------------------------------- ---------------
e59bf31c-49a4-4638-bf6e-7d1be60f4dbb                   1
c0dabf78-d9ca-4072-832e-aeb618c7ed14                   2

я добавляю столбец TYPE1 С ограничением Check (TYPE1_VAL1 или TYPE1_VAL2) и значение по умолчанию TYPE1_VAL2 :

alter table SAMPLE_TABLE add TYPE1 varchar(10) default 'TYPE1_VAL2' not null check(TYPE1 in ('TYPE1_VAL1', 'TYPE1_VAL2'));

Table altered.

Я вижу, что значение по умолчанию (TYPE1_VAL2) правильно заполнены:

select * from SAMPLE_TABLE ;

ID                                       BUSINESS_KEY    TYPE1
---------------------------------------- --------------- ----------
e59bf31c-49a4-4638-bf6e-7d1be60f4dbb                   1 TYPE1_VAL2
c0dabf78-d9ca-4072-832e-aeb618c7ed14                   2 TYPE1_VAL2

я добавляю еще один столбец TYPE2 с другим ограничением проверки (TYPE2_VAL1 или TYPE2_VAL2) и значение по умолчанию TYPE2_VAL2 :

alter table SAMPLE_TABLE add TYPE2 varchar(15) default 'TYPE2_VAL2' not null check(TYPE2 in ('TYPE2_VAL1', 'TYPE2_VAL2'));

Table altered.

и снова видим, что значение по умолчанию (TYPE2_VAL2) правильно :

SYSTEM(SYSTEM) @ DB_USER > select * from SAMPLE_TABLE ;

ID                                       BUSINESS_KEY    TYPE1      TYPE2
---------------------------------------- --------------- ---------- ---------------
e59bf31c-49a4-4638-bf6e-7d1be60f4dbb                   1 TYPE1_VAL2  TYPE2_VAL2
c0dabf78-d9ca-4072-832e-aeb618c7ed14                   2 TYPE1_VAL2  TYPE2_VAL2

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

ALTER TABLE SAMPLE_TABLE DROP COLUMN TYPE1;

Table altered.

select * from SAMPLE_TABLE ;

ID                                       BUSINESS_KEY    TYPE2
---------------------------------------- --------------- ---------------
e59bf31c-49a4-4638-bf6e-7d1be60f4dbb                   1 TYPE1_VAL2
c0dabf78-d9ca-4072-832e-aeb618c7ed14                   2 TYPE1_VAL2

так где же раньше TYPE2 содержит TYPE2_VAL2, внезапно, после падения он содержит TYPE1_VAL2. Это похоже на то, как если бы контрольное ограничение отброшенного столбца переместилось в этот столбец.

это происходит в нашей тестовой среде, где мы запускаем Oracle Database 11g Release 11.2.0.4.0-64bit Production на Linux.

на нашем локальном CentOS / Oracle XE у нас нет этой проблемы.

есть идеи, что могло вызвать это и как мы можем предотвратить это. Это по дизайну / ошибка / ошибка с нашей стороны ?

1 ответов


это ошибка Oracle.

Он запускается путем добавления столбца с обоими NOT NULL ограничение и DEFAULT значение для существующей таблицы.

чтобы добавить столбец быстро, Oracle 11g сохраняет значение по умолчанию в словаре данных. Oracle называет это "добавить оптимизацию столбцов".

это быстрее, чем записывать значение по умолчанию в каждую строку таблицы. Затем предполагается, что механизм запросов заменит любой NULL в строке таблицы значением по умолчанию из словарь данных. К сожалению, есть несколько ошибок, связанных с этим. Ваш, по-видимому, является примером:

17325413 падение столбца со значением по умолчанию и не нулевое определение заканчивается вверх с упавшими данными столбца удара диска, ведущего к коррупции

вы можете проверить, какие столбцы были добавлены следующим образом:

 select owner, object_name, name 
 from dba_objects, col$
 where bitand(col$.PROPERTY,1073741824)=1073741824
 and object_id=obj#;

в нашем случае мы были ужалены другой ошибкой, которая вернула неправильные результаты для SELECT FOR UPDATE.

задаем параметр _add_col_optim_enabled=FALSE чтобы отключить эту "оптимизацию". Кроме того, вы можете перейти на более позднюю версию Oracle, где эти ошибки будут устранены.

обновление или установка вышеуказанного параметра не исправит существующую таблицу, которая повреждена. Вы должны воссоздать эту таблицу.