2012-02-01 7 views
10

PostgreSQL에서 COPY 문을 사용하여 대량 레코드를 삽입하려고합니다. 내가 아는 것은 시퀀스 ID가 업데이트되지 않고 나중에 레코드를 삽입하려고하면 중복 된 시퀀스 ID가 throw된다는 것입니다. COPY을 수행 한 후 레코드 수를 얻기 위해 시퀀스 번호를 수동으로 업데이트해야합니까? COPY을 수행하는 동안 해결책이 없습니까? 즉, 시퀀스 변수, 즉 테이블의 기본 키 필드를 늘리십시오. 이것에 대해 저를 명확히하십시오. 미리 감사드립니다!PostgreSQL에서 COPY가 수행 될 때 시퀀스가 ​​업데이트되지 않는 이유는 무엇입니까?

예를 들어, 200 레코드를 삽입하면 COPY이 좋고 내 테이블에 모든 레코드가 표시됩니다. 나중에 수동으로 레코드를 삽입하면 duplicate sequence ID error이라고 표시됩니다. 이것은 정상적으로 INSERT하는 동안 COPYing하는 동안 시퀀스 ID를 증가시키지 않았다는 것을 의미합니다. 최대 레코드 수를 설정하기 위해 시퀀스 ID를 지시하는 대신 대량 복사 옵션 중에 시퀀스 ID를 증가 시키려면 COPY 명령을 교육하는 메커니즘이 없습니까?

답변

3

시퀀스를 증가시키는 자매 테이블 인 insert into mytable select * from sister으로 복사 할 수 있습니다. 당신의로드 된 데이터는 id 필드가있는 경우

, 삽입을 위해 그것을 선택하지 : insert into mytable (col1, col2, col3) select col1, col2, col3 from sister

+0

감사합니다. – siva

+0

+1이 작동합니다. – pilcrow

20

을 당신이 질문

내가 수동으로 레코드 수를 얻기 위해 일련 번호를 업데이트해야 COPY를 수행 한 후?

예, 당신은 documented here로한다 :

Update에서 복사 후 시퀀스 값 :

| BEGIN; 
| COPY distributors FROM 'input_file'; 
| SELECT setval('serial', max(id)) FROM distributors; 
| END; 

당신은 쓰기 :

을 증가하지 않았다. 정상적인 INSERT 작업 동안 COPYing 동안 작업 ID는 잘 작동합니다.

하지만 그렇지 않습니다! :) 보통의 INSERT를 수행 할 때는 일반적으로 SEQUENCE가 지원하는 기본 키에 대한 명시 적 값을 지정하지 않습니다. 당신이 그랬다면 당신이 지금 겪고있는, 당신은 같은 문제에 실행됩니다 :

postgres=> create table uh_oh (id serial not null primary key, data char(1)); 
NOTICE: CREATE TABLE will create implicit sequence "uh_oh_id_seq" for serial column "uh_oh.id" 
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "uh_oh_pkey" for table "uh_oh" 
CREATE TABLE 
postgres=> insert into uh_oh (id, data) values (1, 'x'); 
INSERT 0 1 
postgres=> insert into uh_oh (data) values ('a'); 
ERROR: duplicate key value violates unique constraint "uh_oh_pkey" 
DETAIL: Key (id)=(1) already exists. 

귀하의 COPY 명령을 물론, 단지 예처럼 위의 INSERT, 명시 적 id 값을 공급하고있다.

+0

시퀀스는 값이 "소비"되면 INSERT 중에 기본값을 채울 때만 증가합니다 (내부적으로 nextval 함수가 사용됨). ID에 값을 제공하면 시퀀스가 ​​사용되지 않으므로 이동하지 않습니다. – peufeu

+0

@peufeu, 네, 맞습니다. – pilcrow

5

나는 이것이 조금 오래되었음을 알고 있지만 어쩌면 누군가가 여전히 답을 찾고 있을지도 모른다.

다른 말로하면 COPY는 INSERT와 비슷한 방식으로 작동하므로 시퀀스가있는 테이블에 삽입하는 경우 시퀀스 필드는 전혀 언급하지 않고 사용자를 대신하여 처리합니다. COPY의 경우 똑같은 방식으로 작동합니다. 하지만 테이블의 모든 필드가 텍스트 파일에 있어야합니다. 정답은 아니요, 그렇지 않지만 기본 동작입니다.이 의도 한대로 작동하고 내 테스트와 마찬가지로 빠른에 관한 것입니다,

COPY $YOURSCHEMA.$YOURTABLE(col1,col2,col3,col4) FROM '$your_input_file' DELIMITER ',' CSV HEADER; 

수동으로 나중에 스키마를 업데이트 할 필요가 없습니다 : 복사 순서를 떠나

밖으로 다음을 수행합니다.

+1

소스 파일 (입력 파일)에 복사하려는 열만 있어야합니다. Postgres는 "똑똑한"것이 아닙니다. 복사 명령에서 지정한 열과 일치하는 열 머리글은 보지 않습니다. 위의 @Phobos 예제에서 입력 파일은 4 개의 열만 가져야합니다. 누군가에게 번거 로움을 덜어주기를 희망합니다 -이 대답은 나를 도왔습니다. –

관련 문제