버전 9.5 이후의 PostgreSQL 에는 ON CONFLICT 절 과 함께 UPSERT 구문이 있습니다. 다음 구문으로 (MySQL과 유사)
INSERT INTO the_table (id, column_1, column_2)
VALUES (1, 'A', 'X'), (2, 'B', 'Y'), (3, 'C', 'Z')
ON CONFLICT (id) DO UPDATE
SET column_1 = excluded.column_1,
column_2 = excluded.column_2;
"upsert"에 대한 postgresql의 이메일 그룹 아카이브를 검색 하면 매뉴얼에서 원하는 작업을 수행하는 예 를 찾을 수 있습니다 .
예 38-2. UPDATE / INSERT 예외
이 예제는 예외 처리를 사용하여 UPDATE 또는 INSERT를 적절하게 수행합니다.
CREATE TABLE db (a INT PRIMARY KEY, b TEXT);
CREATE FUNCTION merge_db(key INT, data TEXT) RETURNS VOID AS
$$
BEGIN
LOOP
-- first try to update the key
-- note that "a" must be unique
UPDATE db SET b = data WHERE a = key;
IF found THEN
RETURN;
END IF;
-- not there, so try to insert the key
-- if someone else inserts the same key concurrently,
-- we could get a unique-key failure
BEGIN
INSERT INTO db(a,b) VALUES (key, data);
RETURN;
EXCEPTION WHEN unique_violation THEN
-- do nothing, and loop to try the UPDATE again
END;
END LOOP;
END;
$$
LANGUAGE plpgsql;
SELECT merge_db(1, 'david');
SELECT merge_db(1, 'dennis');
9.1 이상의 CTE를 사용하여 해커 메일 링리스트 에이를 대량으로 수행하는 방법에 대한 예가있을 수 있습니다 .
WITH foos AS (SELECT (UNNEST(%foo[])).*)
updated as (UPDATE foo SET foo.a = foos.a ... RETURNING foo.id)
INSERT INTO foo SELECT foos.* FROM foos LEFT JOIN updated USING(id)
WHERE updated.id IS NULL;
보다 명확한 예는 a_horse_with_no_name의 답변 을 참조하십시오 .