2013-09-04 1 views
0

특별히 ID를 입력하지 않고 자동 증가 ID가없는 테이블에 새 레코드를 삽입 할 수 있습니까? ID가 lastId + 1이되기를 바랄뿐입니다.포스트 그레스에 삽입 SQL

INSERT INTO lists VALUES (id,'KO','SPH', '5') // 새 ID

+5

그래서 동작을 시퀀스를 사용하지 않고 시퀀스 ("자동 증가")와 같게하려고합니다. 왜 안돼? 이러한 것들은 동시 삽입으로 쉽게 얻을 수있는 문제점을 해결하기 위해 존재합니다. – deceze

+0

DB 구조를 변경하지 않고 새 레코드를 삽입하고 싶습니다 ... – Jacob

+0

예외적 인 경우, 괜찮습니다 ... 이것이 일반적인 조작법 인 경우 데이터베이스 구조를 변경해야합니다. – deceze

답변

5

에 의해 계산하는 경우! EVER! 그렇게 생각하지 마십시오!

수도는 (그렇지 않은) 것이 잘못된 솔루션은 당신을 위해 작동합니다 :

INSERT INTO lists VALUES ((SELECT max(id)+1 FROM lists),'KO','SPH', '5'); 

하지만, 누군가가, 둘 다 얻을 것 같은 시간에 삽입 할 경우 동일한 id, 잘못된 결과가 발생할 수 있습니다. sequence 또는 좀 더 신뢰할 수있는 메커니즘을 사용해야합니다 (보조 테이블은 시퀀스에 구멍이있을 수없는 경우 일반적이지만 [잠길 것입니다]). 당신도 쉽게 할 serial 데이터 유형을 사용할 수 있습니다 (이 아래 시퀀스를 생성) :

CREATE TABLE lists(id serial, col2 text, col3 text, ...); 
-- If you don't specify "id", it will autogenerate for you: 
INSERT INTO lists(col2, col3, ...) VALUES('KO','SPH', ...); 
-- You can also specify using DEFAULT (the same as above): 
INSERT INTO lists(id, col2, col3, ...) VALUES(DEFAULT, 'KO','SPH', ...); 

당신은 정말, 정말, 정말, 생성 및 시퀀스를 사용할 수 없습니다, 당신은 위와 같이 할 수 있다면, 하지만 당신은 (PL/pgSQL의에서) 그런 일합니다 (id 필드 PK 또는 영국, 읽기 최선을 다하고 트랜잭션을 사용하고 가정) 예외를 처리해야합니다 :

DECLARE 
    inserted bool = false; 
BEGIN 
    WHILE NOT inserted LOOP; 
     BEGIN 
      INSERT INTO lists 
      VALUES ((SELECT coalesce(max(id),0)+1 FROM lists),'KO','SPH', '5'); 
      inserted = true; 
     EXCEPTION 
      WHEN unique_violation THEN 
       NULL; -- do nothing, just try again 
     END; 
    END LOOP; 
END; 

그러나 다시, 내가보기 엔 당신을 추천합니다 그것을 피하기 위해 : 시퀀스를 사용하고 행복하게 ... = D

또한 예를 들어 알지만, INSERT INTO 절에 명시적인 열 목록을 사용하십시오.

+0

데이터가없고 max (id) + 1을 수행하면 어떻게됩니까? – maazza

+0

@maazza :'max'는'NULL'을 반환 할 것이고 (NULL을 반환하면'NULL'을 반환합니다), 간단하게'COALESCE'로 처리 할 수 ​​있습니다. 응답을 업데이트 할 것입니다. – MatheusOl

+0

공정하게 , 경고는 오히려 멜로 드라마틱하다. id 속성에 대한 주요 제약 조건을 제공하면 삽입 중 하나가 실패한다는 것이 최악의 경우입니다. – beldaz

0

이 시도 : 또는

INSERT INTO lists VALUES 
(
    (select coalesce(count(*),0) from lists) + 1, 
    'KO','SPH', '5' 
) 

:

INSERT INTO lists VALUES 
(
    (select coalesce(max(id),0) from lists) + 1, 
    'KO','SPH', '5' 
) 

당신이 당신의 필드가 자동 증가해야 ID를 지정하지합니다.

당신은 ID (순서)로 GUID를 사용하십시오 당신이 필드를 지정해야하지만 값이 그렇게하지 마십시오 DBMS

+1

동시에 실행될 경우 잘못된 결과가 생성됩니다. 이러한 ID를 생성하는 유일한 방법은 시퀀스입니다. –

+0

'목록에서 병합 (count (*), 0)을 선택하십시오.'이것은 마지막 키를 생성하지 않았습니다. – Jacob

+1

@Jacob : 마지막 ID + 1을 말하면 정수 ID가 있다고 생각하면 변경할 수 있습니다 –

관련 문제