2009-02-04 3 views
180

Я добавляю новый, «NOT NULL» столбец в мою базу данных Postgresql с помощью следующего запроса (облагороженный для Интернета):Как добавить столбец в базу данных Postgresql, которая не допускает null?

ALTER TABLE mytable ADD COLUMN mycolumn character varying(50) NOT NULL; 

Каждый раз, когда я запускаю этот запрос, я получаю следующее сообщение об ошибке:

ERROR: column "mycolumn" contains null values 

Я в тупик. Где я иду не так?

ПРИМЕЧАНИЕ. Я использую pgAdmin III (1.8.4) в первую очередь, но я получил ту же ошибку, когда я запустил SQL из Terminal.

ответ

305

Вы должны установить значение по умолчанию.

ALTER TABLE mytable ADD COLUMN mycolumn character varying(50) NOT NULL DEFAULT 'foo'; 

... some work (set real values as you want)... 

ALTER TABLE mytable ALTER COLUMN mycolumn DROP DEFAULT; 
+1

Хорошее решение. Я не мог попасть в онлайн-документы postgres по какой-то причине, чтобы увидеть, что будет синтаксисом для этого. –

+3

@SeanBright, вы можете получить доступ к postgres doc в автономном режиме, выполнив 'man ALTER_TABLE' :) –

+0

@ allan.simon Я никогда раньше не использовал PostgreSQL, и у меня его нет нигде. –

47

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

+6

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

+1

См. Этот ответ для примера: http://stackoverflow.com/a/516016/32453 – rogerdpack

5

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

1

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

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

+3

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

+1

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

+0

Например, используя подход DEFAULT, вы добавите это значение по умолчанию для каждой строки. Не знаете, как Postgres блокирует таблицу при этом. Или, если порядок столбцов имеет значение, вы не можете просто добавить столбец с помощью команды ALTER. – alphadogg

2

Задание значения по умолчанию также будет работать, если значение по умолчанию является подходящим.

+1

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

52

Как наблюдали другие, вы должны либо создать столбец с нулевым значением, либо задать значение DEFAULT. Если этого не достаточно гибкое (например, если вам нужно новое значение, которое будет вычисляться для каждой строки по отдельности как-то), вы можете использовать тот факт, что в PostgreSQL, все команды DDL может выполняться внутри транзакции:

BEGIN; 
ALTER TABLE mytable ADD COLUMN mycolumn character varying(50); 
UPDATE mytable SET mycolumn = timeofday(); -- Just a silly example 
ALTER TABLE mytable ALTER COLUMN mycolumn SET NOT NULL; 
COMMIT; 
+1

, даже в транзакции, NOT NULL применяется немедленно, поэтому сначала нужно добавить столбец, заполнить значения, а затем добавить NOT NULL - как это делает ответ. (проверено на postgres 9.6) –

0

этот запрос будет автоматически обновлять аннулирует

ALTER TABLE mytable ADD COLUMN mycolumn character varying(50) DEFAULT 'whatever' NOT NULL; 
-3

Это работает для меня: :)

ALTER TABLE your_table_name ADD COLUMN new_column_name int; 
+1

В вашем запросе нет ограничения 'NOT NULL'. Конечно, он работает. – Sylvain

 Смежные вопросы

  • Нет связанных вопросов^_^