[PostgreSQL] UPSERT

Younghwan Cha·2022년 11월 1일
0

Database

목록 보기
10/16
post-thumbnail

UPSERT?

어디서 많이 본 것 같은 데 무언가 이상하다. INSERT 도 아닌것이 UPDATE 도 아니고...
맞다. 이 두개를 합쳐 놓은 것(UPDATE + INSERT)이 UPSERT 이다.
우리가 DB 를 사용하다보면 어떤 row 는 INSERT, 어떤 row 는 UPDATE 를 하는 것과 같이 INSERT 와 UPDATE 가 섞여서 이루어져야 할 때가 있다. 이를 UPSERT 라고 부르게 된다.

INSERT INTO student (
	id, 
    name, 
    age
) VALUES ${sql.join(insertQuery, sql`, `)}
ON CONFLICT (id)
DO ...

UPDATE 를 하는 경우는 ON CONFLICT 가 났을 경우이다.
ON CONFLICT (id) 와 같이 특정 컬럼에서 충돌이 났을 때 취할 행동(DO)을 정의 할 수 있다.
이는

  • DO NOTHING 과 같이 아무것도 하지 않거나,
  • DO UPDATE SET ~ 과 같이 특정 열을 업데이트 할 수 있다.

DO UPDATE SET ~ 구문을 한번이라도 사용해본 사람은 한가지 의문이 들것이다.

'업데이트 할 값을 어떻게 접근해서 가져오지..?'

이 질문에 답을 해보자.
우리가 업데이트시 사용 할 수 있는 값에는 두가지가 있다.
1. 기존의 데이터
2. 새로 INSERT 하는 데이터

위에 예시를 다시 보자.

INSERT INTO student (
	id, 
    name, 
    age
) VALUES ${sql.join(insertQuery, sql`, `)}
ON CONFLICT (id)
DO UPDATE
	SET id = 'conflict made here' || student.id

기존의 데이터를 사용하길 원한다면 상단과 같이 <table>.<col> 로 접근하면 된다.
그렇다면 INSERT 한 데이터를 사용하고 싶은 경우엔?
사실, 1번 경우보다는 이 2번 경우가 훨씬 더 많을 것이다. 이때엔, 우리의 postgres 가 준 선물, EXCLUDED 를 사용하면 해결된다.

INSERT INTO student (
	id, 
    name, 
    age
) VALUES ${sql.join(insertQuery, sql`, `)}
ON CONFLICT (id)
DO UPDATE
	SET id = EXCLUDED.id
profile
개발 기록

0개의 댓글