Data tidak pernah diam: harga naik, stok berkurang, nama produk diperbaiki. Perintah UPDATE mengubah nilai pada baris yang sudah tersimpan — tanpa menghapus barisnya dan tanpa menyisipkan baris baru. Seperti INSERT, perintah ini menulis ke tabel sungguhan, dan karena itu datang dengan satu aturan paling penting di seluruh materi manipulasi data: WHERE hampir selalu wajib. Lupa WHERE berarti semua baris ikut berubah, dan kecelakaan semacam ini adalah cerita klasik yang berakhir dengan permintaan pemulihan backup.

Menyiapkan Tabel Latihan #

Kita pakai tabel produk yang dilengkapi kolom stok dan satu CHECK constraint yang menjaga harga tetap positif — constraint itu akan bekerja untuk kita di bagian akhir chapter:

sql buat-tabel.sql
CREATE TABLE produk (
    id       integer PRIMARY KEY,
    nama     text NOT NULL,
    kategori text NOT NULL,
    harga    numeric(10, 2) NOT NULL CHECK (harga > 0),
    stok     integer NOT NULL DEFAULT 0
);

INSERT INTO produk (id, nama, kategori, harga, stok) VALUES
    (1, 'Buku Tulis', 'alat tulis', 4500, 120),
    (2, 'Pulpen Hitam', 'alat tulis', 3000, 200),
    (3, 'Kertas HVS A4', 'kertas', 55000, 40),
    (4, 'Map Plastik', 'alat tulis', 12000, 25),
    (5, 'Amplop Coklat', 'kertas', 1500, 300);

SELECT id, nama, kategori, harga, stok FROM produk ORDER BY id;

Output yang Dihasilkan:

text
CREATE TABLE
INSERT 0 5
 id |     nama      |  kategori  |  harga   | stok 
----+---------------+------------+----------+------
  1 | Buku Tulis    | alat tulis |  4500.00 |  120
  2 | Pulpen Hitam  | alat tulis |  3000.00 |  200
  3 | Kertas HVS A4 | kertas     | 55000.00 |   40
  4 | Map Plastik   | alat tulis | 12000.00 |   25
  5 | Amplop Coklat | kertas     |  1500.00 |  300
(5 rows)

Lima baris produk siap diedit. Kolom stok sengaja diberi nilai awal yang beragam supaya perubahan yang kita lakukan mudah dibandingkan baris demi baris.

Mengubah Satu Kolom pada Baris Tertentu #

Anatomi UPDATE terdiri dari tiga bagian: tabel tujuan setelah UPDATE, pasangan kolom-nilai setelah SET, lalu kondisi pencarian setelah WHERE. Contoh pertama mengubah satu kolom pada satu baris — stok Kertas HVS A4 dikoreksi menjadi 50 karena hasil stock opname:

UPDATE produk SET stok = 50 WHERE id = 3;

SELECT id, nama, stok FROM produk WHERE id = 3;

Output yang Dihasilkan:

text
UPDATE 1
 id |     nama      | stok 
----+---------------+------
  3 | Kertas HVS A4 |   50
(1 row)

Dua bagian yang menentukan sasaran:

  1. SET stok = 50 menetapkan kolom apa yang diubah dan nilai barunya. Nilai di sini bisa literal (seperti 50), ekspresi, atau bahkan hasil subquery — kita naik tingkat sebentar lagi.
  2. WHERE id = 3 memfilter baris mana yang boleh berubah. Hanya baris dengan id = 3 yang tersentuh; empat baris lainnya tidak dibaca ulang nilainya.

Tag UPDATE 1 di output adalah laporan jumlah baris yang berhasil diubah — satu baris, tepat sasaran. SELECT sesudahnya memverifikasi hasilnya langsung di tabel.

Ekspresi: Mengubah Nilai Berdasar Nilai Lama #

Menaikkan semua harga kertas sebesar 10% tidak mungkin ditulis sebagai daftar literal, karena nilai barunya bergantung pada nilai lamanya. Di sinilah bentuk SET kolom = ekspresi berperan — harga * 1.1 dibaca dari nilai harga baris itu sendiri, baris demi baris:

UPDATE produk SET harga = harga * 1.1
WHERE kategori = 'kertas';

SELECT id, nama, harga FROM produk ORDER BY id;

Output yang Dihasilkan:

text
UPDATE 2
 id |     nama      |  harga   
----+---------------+----------
  1 | Buku Tulis    |  4500.00
  2 | Pulpen Hitam  |  3000.00
  3 | Kertas HVS A4 | 60500.00
  4 | Map Plastik   | 12000.00
  5 | Amplop Coklat |  1650.00
(5 rows)

Tag UPDATE 2 melaporkan dua baris berubah — tepat jumlah produk kategori kertas. Harga Kertas HVS A4 berubah dari 55000.00 menjadi 60500.00, dan Amplop Coklat dari 1500.00 menjadi 1650.00, sementara tiga produk alat tulis tidak tersentuh. Perhatikan juga bahwa angka tag ini adalah satu-satunya tempat PostgreSQL memberi tahu seberapa banyak baris yang berubah — angka yang lebih besar dari yang Anda niatkan adalah alarm pertama bahwa kondisi WHERE Anda terlalu longgar.

Mengubah Beberapa Kolom Sekaligus #

Satu UPDATE boleh mengubah banyak kolom: cukup pisahkan pasangan kolom = nilai dengan koma di dalam SET. Ini bukan sekadar hemat ketikan — seluruh perubahan berlaku secara atomik pada baris yang sama, tidak ada momen ketika satu kolom sudah berubah sementara kolom lainnya belum:

UPDATE produk
SET harga = 5000, stok = 100, nama = 'Buku Tulis Premium'
WHERE id = 1;

SELECT id, nama, harga, stok FROM produk ORDER BY id;

Output yang Dihasilkan:

text
UPDATE 1
 id |        nama        |  harga   | stok 
----+--------------------+----------+------
  1 | Buku Tulis Premium |  5000.00 |  100
  2 | Pulpen Hitam       |  3000.00 |  200
  3 | Kertas HVS A4      | 60500.00 |   50
  4 | Map Plastik        | 12000.00 |   25
  5 | Amplop Coklat      |  1650.00 |  300
(5 rows)

Baris id = 1 kini menjadi Buku Tulis Premium dengan harga 5000.00 dan stok 100 — tiga kolom berubah dalam satu operasi berlabel UPDATE 1, karena yang dihitung adalah baris, bukan jumlah kolom. Pemisahnya koma; kesalahan umum pemula adalah memakai kata AND seperti gaya bahasa sehari-hari (SET harga = 5000 AND stok = 100), yang ditolak PostgreSQL sebagai syntax error.

Lupa WHERE: Kecelakaan yang Mengubah Semuanya #

Tiba saatnya membuktikan kenapa peringatan di pembuka chapter itu serius. Perintah berupa UPDATE tanpa klausa WHERE tetap valid secara sintaks — PostgreSQL menjalankannya tanpa keluhan, pada setiap baris tabel:

UPDATE produk SET stok = 0;

SELECT id, nama, stok FROM produk ORDER BY id;

Output yang Dihasilkan:

text
UPDATE 5
 id |        nama        | stok 
----+--------------------+------
  1 | Buku Tulis Premium |    0
  2 | Pulpen Hitam       |    0
  3 | Kertas HVS A4      |    0
  4 | Map Plastik        |    0
  5 | Amplop Coklat      |    0
(5 rows)

Tag UPDATE 5 dan hasil SELECT memperlihatkan bencananya: stok kelima produk menjadi 0 sekaligus, termasuk Buku Tulis Premium yang baru saja kita atur. Perintah yang kita maksudkan “koreksi satu produk” ternyata menghapus seluruh informasi stok toko. Pada data sungguhan, langkah penyelamatan pertama adalah ROLLBACK bila kita masih berada di dalam transaction yang sama — topik Section Transactions; setelah perintah ter-commit, hanya backup yang bisa mengembalikan keadaan.

Constraint Tetap Dijalankan Saat UPDATE #

Constraint yang didefinisikan di tabel tidak hanya diperiksa saat INSERT — setiap UPDATE juga melewati pemeriksaan yang sama. Tabel kita punya CHECK (harga > 0), jadi mencoba menetapkan harga negatif akan ditolak mentah-mentah:

UPDATE produk SET harga = -100 WHERE id = 2;

Output yang Dihasilkan:

text
psql:update-check-error.sql:1: ERROR:  new row for relation "produk" violates check constraint "produk_harga_check"
DETAIL:  Failing row contains (2, Pulpen Hitam, alat tulis, -100.00, 0).

Error ini sebenarnya berita baik: nilai yang melanggar aturan bisnis tidak pernah tersimpan, dan psql langsung menghentikan eksekusi di titik itu. Baris Pulpen Hitam tetap membawa harga lamanya 3000.00 — hanya percobaan perubahan yang gagal. Detail pada pesan error juga memperlihatkan stok baris itu masih 0, jejak dari kecelakan UPDATE tanpa WHERE di bagian sebelumnya; penolakan constraint tidak “menyembuhkan” data lama, ia hanya mencegah data buruk yang baru.

Dengan UPDATE kita sudah bisa memperbaiki nilai yang salah. Pertanyaan berikutnya: bagaimana kalau barisnya sendiri yang harus hilang dari tabel — misalnya produk yang sudah tidak dijual? Itu pekerjaan DELETE, chapter berikutnya.

Referensi #

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

buat-tabel.sql

Unduh berkas
sql
CREATE TABLE produk (
    id       integer PRIMARY KEY,
    nama     text NOT NULL,
    kategori text NOT NULL,
    harga    numeric(10, 2) NOT NULL CHECK (harga > 0),
    stok     integer NOT NULL DEFAULT 0
);

INSERT INTO produk (id, nama, kategori, harga, stok) VALUES
    (1, 'Buku Tulis', 'alat tulis', 4500, 120),
    (2, 'Pulpen Hitam', 'alat tulis', 3000, 200),
    (3, 'Kertas HVS A4', 'kertas', 55000, 40),
    (4, 'Map Plastik', 'alat tulis', 12000, 25),
    (5, 'Amplop Coklat', 'kertas', 1500, 300);

SELECT id, nama, kategori, harga, stok FROM produk ORDER BY id;

update-check-error.sql

Unduh berkas
sql
UPDATE produk SET harga = -100 WHERE id = 2;

update-ekspresi.sql

Unduh berkas
sql
UPDATE produk SET harga = harga * 1.1
WHERE kategori = 'kertas';

SELECT id, nama, harga FROM produk ORDER BY id;

update-multi-kolom.sql

Unduh berkas
sql
UPDATE produk
SET harga = 5000, stok = 100, nama = 'Buku Tulis Premium'
WHERE id = 1;

SELECT id, nama, harga, stok FROM produk ORDER BY id;

update-satu-kolom.sql

Unduh berkas
sql
UPDATE produk SET stok = 50 WHERE id = 3;

SELECT id, nama, stok FROM produk WHERE id = 3;

update-tanpa-where.sql

Unduh berkas
sql
UPDATE produk SET stok = 0;

SELECT id, nama, stok FROM produk ORDER BY id;