null을 허용하지 않는 Postgresql 데이터베이스에 열을 어떻게 추가합니까?


243

다음 쿼리를 사용하여 Postgresql 데이터베이스에 "NOT NULL"열을 새로 추가하고 있습니다 (인터넷에서 삭제).

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

이 쿼리를 실행할 때마다 다음과 같은 오류 메시지가 나타납니다.

ERROR:  column "mycolumn" contains null values

나는 충격을 받았다. 내가 어디로 잘못 가고 있니?

참고 : 나는 주로 pgAdmin III (1.8.4)를 사용하고 있지만 터미널 내에서 SQL을 실행할 때 동일한 오류가 발생했습니다.

답변:


400

기본값을 설정해야합니다.

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 문서에 연결할 수 없었습니다.
Sean Bright

4
@SeanBright, 다음을 수행하여 오프라인으로 postgres 문서에 액세스 할 수 있습니다 man ALTER_TABLE :)
allan.simon

@ allan.simon 이전에는 PostgreSQL을 사용한 적이 없으며 어디에도 설치되어 있지 않습니다.
Sean Bright

2
명확히하기 위해 : 기본값은 기존 행을 업데이트하는 데만 필요하므로 바로 그 후에 삭제할 수 있습니다. 테이블이 변경 될 때 기존의 모든 행이 업데이트되었습니다 (시간이 걸릴 수 있음)
MSalters

2
다른 열을 사용하여 기존 행의 초기 값을 계산하려는 경우에는 작동하지 않습니다. j_random_hacker의 답변으로 가능 해져 더욱 강력 해집니다.
jpmc26

82

다른 사람들이 관찰했듯이 널 입력 가능 열을 작성하거나 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;

7
트랜잭션에서도 NOT NULL이 즉시 적용되므로 먼저이 대답과 같이 열을 추가하고 값을 채운 다음 NOT NULL을 추가해야합니다. (postgres 9.6에서 테스트)
Beni Cherniavsky-Paskin

48

테이블에 행이 이미 있으므로 ALTER명령문이 NULL기존의 모든 행에 대해 새로 작성된 열에 삽입하려고합니다 . 열을 허용으로 추가 NULL한 다음 원하는 값으로 열을 채운 NOT NULL후 나중에 설정해야합니다 .


7
그것을하는 방법의 예는 정말 좋았을 것입니다. 그렇지 않으면 Luc의 솔루션이 더 완벽하고 사용할 준비가 된 것 같습니다.
Victor Farazdagi 2012

5

기본값을 정의하거나 Sean이 말한 것을 수행하고 기존 행에 채워질 때까지 null 제약 조건없이 추가해야합니다.


2

기본값이 적절하다고 가정하면 기본값을 지정해도 작동합니다.


2
수정 된 구문을 제공하여 기본값을 가진 열을 만들도록 대답을 향상시킵니다 (예시).
hardmath

1

또는 추가 열을 사용하여 임시 테이블로 새 테이블을 작성하고 널 입력 불가능한 새 열을 채우는 데 필요한만큼 조작하면서 데이터를이 새 테이블에 복사 한 다음 2 단계 이름 변경을 통해 테이블을 교환하십시오.

예, 더 복잡하지만 라이브 테이블에서 큰 업데이트를 원하지 않는 경우이 방법을 사용해야 할 수도 있습니다.


3
나는 당신을 -1하지는 않았지만 이것에 미묘한 어려움이있을 것이라고 생각합니다. 이름 대신 테이블을 변경합니다 (변경되지 않음).
j_random_hacker

1
예, 새 표는 색인 등을 포함하여 원본의 정확한 사본이어야합니다. 너무 짧아서 나쁘다. 그 이유는 테이블에 ALTER를 수행하는 데 미묘한 어려움이 있기 때문에 때로는 준비해야하기 때문입니다.
alphadogg

예를 들어 DEFAULT 접근 방식을 사용하면 각 행에 해당 기본값을 추가합니다. 이 작업을 수행 할 때 Postgres가 어떻게 테이블을 잠그는 지 확실하지 않습니다. 또는 열 순서가 중요한 경우 ALTER 명령을 사용하여 열을 추가 할 수 없습니다.
alphadogg

알터 테이블은 PostgreSQL 문서에 따라 테이블을 잠급니다. 또한 열 순서에 의존하는 코드가 깨졌습니다 (물론 제어 할 수없는 것 같습니다).
j_random_hacker

2
이 방법은 외래 키 인덱스도 테이블을 모두 참조해야하므로 테이블을 참조하는 경우 특히 문제가됩니다.
Aryeh Leib Taurog

0

이 쿼리는 null을 자동 업데이트합니다.

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

-6

이것은 나를 위해 일했다 : :)

ALTER TABLE your_table_name ADD COLUMN new_column_name int;

2
NOT NULL쿼리 에는 제약 이 없습니다 . 물론 작동합니다.
Sylvain
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.