여러 문제.
확장 된 설정 :
CREATE TABLE a (
pk_a int PRIMARY KEY
, a int
, comment text -- added column to make effect clear
);
CREATE TABLE b (
pk_b int PRIMARY KEY
, b int
, comment text
);
INSERT INTO a VALUES (1, 11, 'comment from a')
, (2, 22, 'comment from a');
INSERT INTO b VALUES (1, 77, 'comment from b');
이것은 작동합니다 :
INSERT INTO b (pk_b, b, comment)
SELECT pk_a, a, comment
FROM a
ON CONFLICT (pk_b) DO UPDATE -- conflict is on the unique column
SET b = excluded.b; -- key word "excluded", refer to target column
결과:
TABLE b;
pk_b | b | comment
------+----+----------------
1 | 11 | comment from b -- updated
2 | 22 | comment from a -- inserted
문제
당신은 혼동 table_a
하고 A
(같은 데모에 @Abelisto 댓글을 달았습니다 ).
소문자로 인용되지 않은 합법적 인 식별자를 사용하면 혼동을 피할 수 있습니다.
마찬가지로 @Ziggy 언급 , ON CONFLICT
단지 실제 작동 고유하거나 배제 제약 조건 위반 . 매뉴얼 :
선택적 ON CONFLICT
절은 고유 한 위반 또는 제외 제한 조건 위반 오류를 발생시키는 대체 조치를 지정합니다.
결과적으로, ON CONFLICT (b)
작동 할 수 없으며 제약이 없습니다. ON CONFLICT (pk_b)
공장.
마찬가지로 @Ziggy도 언급 , 소스 테이블 이름이 표시되지 않습니다 의 UPDATE
일부입니다. 매뉴얼 :
SET
와 WHERE
의 조항 ON CONFLICT DO UPDATE
테이블의 이름 (또는 별명)를 사용하여 기존 행에 대한 액세스 권한을 가지고 있고,에 특별한 사용하여 삽입을 위해 제안 된 행 excluded
표를 .
대담한 강조 광산.
파트 에서 소스 테이블 의 열 이름을 사용할 수도 없습니다 UPDATE
. 대상 행 의 열 이름 이어야합니다 . 그래서 당신은 정말로 원합니다 :
SET b = excluded.b
매뉴얼을 한 번 더 :
모든 행당 BEFORE INSERT
트리거 의 효과는 제외 된 값에 반영됩니다. 이러한 효과는 삽입에서 제외되는 행에 영향을 줄 수 있기 때문입니다.
CREATE TABLE A...
a
아닌 테이블을 만듭니다table_a
.