Tabel yang sudah dibangun dengan constraint rapi masih berupa lemari kosong — sampai baris pertama masuk, SELECT tidak akan mengembalikan apa pun. Statement INSERT adalah pintu masuknya. Chapter ini mengisi tabel pelanggan dan produk milik toko kita secara bertahap: satu baris, banyak baris sekaligus, mengandalkan DEFAULT, lalu menyalin dari tabel lain — ditutup dengan tiga error yang paling sering dijumpai dan cara membacanya.

INSERT Satu Baris #

Kita mulai dari bentuk paling dasar. Buat database latihan baru dengan skema dua tabel berikut — sama persis dengan hasil akhir Chapter Constraint pada Tabel — lalu masukkan pelanggan pertama:

sql
CREATE TABLE pelanggan (
    id INTEGER PRIMARY KEY,
    nama TEXT NOT NULL,
    kota TEXT
);

CREATE TABLE produk (
    id INTEGER PRIMARY KEY,
    nama TEXT NOT NULL UNIQUE,
    harga INTEGER NOT NULL CHECK (harga >= 0),
    stok INTEGER DEFAULT 0
);
text
sqlite> INSERT INTO pelanggan (nama, kota) VALUES ('Budi', 'Jakarta');
sqlite> SELECT * FROM pelanggan;
1|Budi|Jakarta
sqlite>

Mari kita bedah satu-satunya statement di atas:

  1. INSERT INTO pelanggan — tabel tujuan data, yaitu pelanggan.
  2. (nama, kota) — daftar kolom yang diisi. Kolom id tidak disebut, sehingga engine mengisinya otomatis dari INTEGER PRIMARY KEY — hasilnya terlihat di output: 1.
  3. VALUES ('Budi', 'Jakarta') — nilai untuk kolom tersebut, urutannya mengikuti daftar kolom: teks 'Budi' masuk ke nama, 'Jakarta' masuk ke kota.

Mendaftarkan kolom secara eksplisit seperti ini adalah kebiasaan yang baik: statement tetap benar walau urutan kolom tabel berubah, dan pembaca langsung tahu nilai mana masuk ke kolom mana.

Banyak Baris Sekaligus #

Satu statement INSERT mampu memuat beberapa baris — cukup pisahkan tiap baris nilai dengan koma:

text
sqlite> INSERT INTO pelanggan (nama, kota) VALUES
   ...>   ('Siti', 'Bandung'),
   ...>   ('Ani', 'Surabaya'),
   ...>   ('Joko', 'Jakarta'),
   ...>   ('Rina', NULL);
sqlite> SELECT * FROM pelanggan;
1|Budi|Jakarta
2|Siti|Bandung
3|Ani|Surabaya
4|Joko|Jakarta
5|Rina|
sqlite>

Nilai NULL pada baris Rina sah: kolom kota tidak memiliki constraint NOT NULL, jadi engine menyimpan pelanggan tanpa kota. Beginilah cara data NULL masuk ke database secara sengaja — bukan karena kecelakaan — dan pada Chapter Memfilter Data dengan WHERE kita akan lihat cara menanganinya.

Sekarang giliran tabel produk. Enam baris pertama memuat stok eksplisit, dan baris ketujuh sengaja tidak menyebut kolom tersebut:

text
sqlite> INSERT INTO produk (nama, harga, stok) VALUES
   ...>   ('Pensil', 3000, 120),
   ...>   ('Buku Tulis', 5500, 45),
   ...>   ('Penghapus', 2500, 80),
   ...>   ('Tas Sekolah', 85000, 12),
   ...>   ('Botol Air', 25000, 30),
   ...>   ('Rautan Pensil', 8000, NULL);
sqlite> INSERT INTO produk (nama, harga) VALUES ('Papan Tulis Kecil', 15000);
sqlite> SELECT * FROM produk;
1|Pensil|3000|120
2|Buku Tulis|5500|45
3|Penghapus|2500|80
4|Tas Sekolah|85000|12
5|Botol Air|25000|30
6|Rautan Pensil|8000|
7|Papan Tulis Kecil|15000|0
sqlite>

Perhatikan dua baris terakhir. Rautan Pensil dimasukkan dengan stok NULL karena stoknya memang belum dihitung. Papan Tulis Kecil dimasukkan tanpa menyebut stok sama sekali — dalam kasus ini DEFAULT 0 bekerja, dan yang tersimpan adalah angka 0. Perbedaan keduanya penting: NULL berarti “belum tahu”, sedangkan 0 berarti “sudah pasti nol”.

Menyalin Data dengan INSERT … SELECT #

Sumber nilai tidak harus berupa literal. INSERT INTO ... SELECT ... menyalin baris hasil query ke tabel tujuan — misalnya membuat tabel khusus pelanggan Jakarta:

text
sqlite> CREATE TABLE pelanggan_jakarta (
   ...>   id INTEGER PRIMARY KEY,
   ...>   nama TEXT NOT NULL,
   ...>   kota TEXT
   ...> );
sqlite> INSERT INTO pelanggan_jakarta (nama, kota)
   ...>   SELECT nama, kota FROM pelanggan WHERE kota = 'Jakarta';
sqlite> SELECT * FROM pelanggan_jakarta;
1|Budi|Jakarta
2|Joko|Jakarta
sqlite>

Bagian SELECT nama, kota FROM pelanggan WHERE kota = 'Jakarta' adalah query biasa; hasilnya dimasukkan ke pelanggan_jakarta kolom demi kolom. Teknik ini adalah fondasi lapisan pelaporan dan agregasi yang dibahas lebih jauh pada Section Query Lanjutan.

Ketika INSERT Ditolak #

Constraint dari Chapter sebelumnya kini menunjukkan taringnya. Tiga penolakan berikut paling sering terjadi:

text
sqlite> INSERT INTO produk (harga) VALUES (50000);
Runtime error: NOT NULL constraint failed: produk.nama (19)
sqlite> INSERT INTO produk (nama, harga) VALUES ('Pensil', 4000);
Runtime error: UNIQUE constraint failed: produk.nama (19)
sqlite> INSERT INTO produk VALUES ('Stiker', 500);
Parse error: table produk has 4 columns but 2 values were supplied
sqlite>

Pesan error ini membawa informasi lengkap: nama constraint yang dilanggar, tabel, dan kolomnya. Penolakan ketiga bukan pelanggaran constraint melainkan kesalahan jumlah — tabel produk punya 4 kolom, sedangkan nilai yang diberikan hanya 2.

Satu sifat penting lagi: statement INSERT bersifat atomik. Jika satu baris di antara banyak baris gagal, seluruh statement dibatalkan tanpa menyisakan setengah pekerjaan:

text
sqlite> INSERT INTO produk (nama, harga, stok) VALUES
   ...>   ('Stiker Motif', 500, 50),
   ...>   ('Pensil', 4000, 10);
Runtime error: UNIQUE constraint failed: produk.nama (19)
sqlite> SELECT COUNT(*) FROM produk;
7
sqlite>

Baris Stiker Motif valid, tetapi baris Pensil menabrak UNIQUE — keduanya batal masuk, dan jumlah baris tetap 7. Data toko kini lengkap; Chapter Membaca Data dengan SELECT mengambil alih di sisi sebaliknya: membacanya kembali.