Ruang penulis
← Kembali ke jurnal
PostgreSQL

Upsert di PostgreSQL dengan ON CONFLICT

Gabungkan insert dan update dalam satu pernyataan untuk data yang mungkin sudah ada.

DTim Diary Coding · 02 Sep 2026 · 2 menit baca

Masalah insert yang mungkin duplikat

Saat menyimpan data dari sumber luar, baris yang sama bisa terkirim lebih dari sekali. Melakukan SELECT untuk mengecek keberadaan data sebelum INSERT rentan terhadap race condition ketika dua proses berjalan bersamaan.

ON CONFLICT DO UPDATE

CREATE TABLE statistik_artikel (
    artikel_id BIGINT PRIMARY KEY,
    jumlah_dilihat BIGINT NOT NULL DEFAULT 0
);

INSERT INTO statistik_artikel (artikel_id, jumlah_dilihat)
VALUES (42, 1)
ON CONFLICT (artikel_id)
DO UPDATE SET jumlah_dilihat = statistik_artikel.jumlah_dilihat + 1;

Pernyataan di atas menambah baris baru jika artikel_id belum ada, atau menambah penghitung jika sudah ada, semuanya dalam satu operasi atomik.

ON CONFLICT DO NOTHING

Jika Anda hanya ingin mengabaikan baris yang sudah ada tanpa mengubah apa pun, gunakan DO NOTHING.

INSERT INTO email_terdaftar (email)
VALUES ('user@contoh.test')
ON CONFLICT (email) DO NOTHING;

Syarat memakai ON CONFLICT

Kolom yang disebut dalam ON CONFLICT harus memiliki UNIQUE constraint atau menjadi primary key. Tanpa itu, PostgreSQL tidak tahu kondisi mana yang dianggap konflik.

Membedakan dengan MERGE

PostgreSQL versi 15 ke atas juga mendukung pernyataan MERGE yang lebih fleksibel untuk kasus insert, update, dan delete sekaligus berdasarkan hasil join. ON CONFLICT tetap lebih ringkas untuk kasus upsert sederhana berbasis satu constraint unik.

Latihan

Ubah contoh statistik di atas agar juga menyimpan waktu terakhir dilihat, dan pastikan kolom tersebut ikut diperbarui saat konflik terjadi.

← Jelajahi catatan lainnya