Sybase ASE: сбой при добавлении столбца NOT NULL без значения DEFAULT. Зачем? - PullRequest
0 голосов
/ 29 августа 2018

Рассмотрим следующую пустую (как без строк) таблицу:

CREATE TABLE my_table(
    my_column CHAR(10) NOT NULL
);

Попытка добавить столбец NOT NULL без DEFAULT завершится неудачей:

ALTER TABLE my_table ADD my_new_column CHAR(10) NOT NULL;

Error:

*[Code: 4997, SQL State: S1000]
ALTER TABLE my_table failed. 
Default clause is required in order to add non-NULL column 'my_new_column'.

Но добавление столбца как NULL и изменение его на NOT NULL будет работать:

ALTER TABLE my_table ADD my_new_column CHAR(10) NULL;
ALTER TABLE my_table MODIFY my_new_column CHAR(10) NOT NULL;

Установка значения по умолчанию, а затем удаление значения по умолчанию также будет работать:

ALTER TABLE my_table ADD my_new_column CHAR(10) DEFAULT '' NOT NULL;
ALTER TABLE my_table REPLACE my_new_column DEFAULT NULL;

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

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Это предположение. Я предполагаю, что Sybase чрезмерно консервативен. Как правило, вы не можете добавить новый столбец not null без значения default в таблицу , в которой есть строки . Это верно для всех баз данных, потому что нет способа заполнить существующие строки для нового столбца.

Я предполагаю, что Sybase просто не проверяет, есть ли в таблице строки, только если она существует. Очевидно, что он не делает проверку для alter.

0 голосов
/ 29 августа 2018

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

Разрешение прямого добавления столбца NOT NULL поставит под угрозу любые существующие записи, если значение по умолчанию отсутствует. Да, мы знаем, что таблица пуста. И база данных может (в конце концов) знать, что таблица пуста в время выполнения ... но она не может знать, что таблица пуста во время компиляции плана выполнения, потому что строка может быть добавлена ​​во время выполнения план определен.

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

Соедините их вместе, и становится трудно просто откатить неудачный запрос, потому что у вас могут быть реальные страницы в разных состояниях. По какой-то причине разработчики решили не допустить этого.

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

...