Menu

INSERT SQLite: Tambah Baris, Bulk Insert, OR IGNORE

Cara kerja INSERT di SQLite: satu baris, banyak baris sekaligus, INSERT...SELECT, nilai default, serta modifier konflik OR IGNORE / OR REPLACE.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

INSERT Menambahkan Baris ke Tabel

INSERT adalah pernyataan yang kamu pakai untuk memasukkan baris baru ke dalam tabel. Bentuknya singkat dan mudah ditebak:

Ada tiga bagian yang perlu diperhatikan:

  • INSERT INTO books: tabel tujuan.
  • (title, author, year): kolom-kolom yang nilainya kamu berikan.
  • VALUES (...): nilai-nilainya, dengan urutan yang sama seperti daftar kolom.

id tidak ada di daftar kolom, jadi SQLite mengisinya secara otomatis (kolom itu INTEGER PRIMARY KEY, yang mendapat rowid). Kolom apa pun yang kamu lewati akan memakai nilai default-nya, atau NULL jika tidak punya default.

Selalu Tuliskan Kolommu

Kamu bisa menghilangkan daftar kolom dan memberi nilai untuk setiap kolom sesuai urutan deklarasinya:

-- Works, but fragile:
INSERT INTO books VALUES (NULL, 'Dune', 'Frank Herbert', 1965);

Jangan lakukan itu. Begitu seseorang menambahkan kolom ke books, setiap pernyataan seperti ini akan rusak atau mulai memasukkan nilai ke kolom yang salah. Tuliskan kolomnya:

Daftar kolom yang eksplisit adalah salah satu bentuk dokumentasi. Pernyataannya jadi bisa dibaca dengan sendirinya, tanpa harus mencari definisi tabelnya.

Menambahkan Banyak Baris

Kamu bisa menambahkan beberapa baris dalam satu pernyataan dengan menuliskan lebih banyak tuple nilai:

Ini lebih rapi daripada tiga pernyataan INSERT terpisah, dan SQLite menganggap semuanya sebagai satu pernyataan. Namun, keuntungan performa yang sebenarnya untuk pemuatan data besar datang dari membungkus insert dalam transaksi. Penjelasannya ada di bagian berikut.

Bulk Insert: Bungkus dalam Transaksi

Secara default, setiap INSERT adalah transaksi tersendiri. SQLite menjalankan fsync di akhir setiap transaksi, dan itulah yang membuat perulangan sederhana jadi lambat, bukan insert-nya.

Kelompokkan insert-nya:

Satu fsync, bukan lima. Untuk ribuan baris, selisihnya bisa mencapai seratus hingga seribu kali lipat. Jika ada yang gagal di dalamnya, ROLLBACK membatalkan seluruh kelompok itu.

Pola ini adalah resep bulk insert. Pakai pola ini baik saat kamu memanggil SQLite dari Python, Node, maupun Rust: bungkus perulanganmu dengan BEGIN / COMMIT.

INSERT ... SELECT: Menyalin dari Tabel Lain

Kamu bisa mengisi tabel dari sebuah query, bukan dari nilai literal:

Kolom dari SELECT dicocokkan berdasarkan posisi dengan daftar kolom milik INSERT. Namanya tidak harus sama, yang penting urutannya. Ini cara standar untuk mengarsipkan baris, membuat tabel laporan, atau menyalin sebagian data saat migrasi.

DEFAULT VALUES dan Kolom yang Dilewati

Jika sebuah kolom punya klausa DEFAULT, kamu bisa tidak menuliskannya di daftar kolom dan SQLite akan mengisi nilai default-nya:

created_at mendapat timestamp saat ini karena kita tidak memberikan nilainya. Jika kamu ingin baris yang seluruhnya berisi nilai default, yang berguna untuk baris penampung, pakai bentuk DEFAULT VALUES:

Dua baris baru, keduanya dengan value = 0 dan id yang diisi otomatis.

INSERT OR IGNORE: Lewati Duplikat

Jika sebuah baris akan melanggar constraint UNIQUE atau PRIMARY KEY, perilaku default-nya adalah menghentikan pernyataan dengan error:

Error: UNIQUE constraint failed: users.email

INSERT OR IGNORE menggantinya dengan "lewati baris yang bermasalah tanpa suara":

Tiga baris bertahan. Duplikatnya dibuang tanpa error. Inilah cara khas SQLite untuk menyatakan "insert jika belum ada" untuk data seed sederhana: tanpa SELECT terpisah untuk memeriksa dulu, tanpa penanganan exception.

INSERT OR REPLACE: Timpa Duplikat

INSERT OR REPLACE menghapus baris yang bentrok dan memasukkan baris baru sebagai gantinya:

Waspadai satu hal: REPLACE adalah DELETE + INSERT, bukan UPDATE. Jika baris yang dihapus dirujuk oleh foreign key dengan ON DELETE CASCADE, baris anak itu ikut terhapus. Dan setiap kolom yang tidak kamu tuliskan di INSERT yang baru akan kembali ke nilai default-nya, bukan mempertahankan nilai lama.

Untuk sebagian besar kasus "update jika ada, insert jika belum", yang sebenarnya kamu butuhkan adalah upsert sungguhan dengan ON CONFLICT ... DO UPDATE. Topik itu dibahas di halamannya sendiri.

Ringkasan Singkat

  • INSERT INTO table (cols) VALUES (...): bentuk dasarnya. Selalu tuliskan kolomnya.
  • Insert banyak baris memakai tuple yang dipisahkan koma setelah VALUES.
  • Untuk pemuatan data yang benar-benar besar, bungkus insert dengan BEGIN / COMMIT.
  • INSERT INTO ... SELECT ... menyalin baris dari sebuah query.
  • DEFAULT VALUES membuat baris hanya dari nilai default; kolom yang dilewati juga kembali ke nilai default-nya.
  • INSERT OR IGNORE melewati baris yang bentrok; INSERT OR REPLACE menimpanya (lewat delete + insert).

Selanjutnya: UPDATE

Menambahkan baris baru separuh cerita. Separuh lainnya adalah mengubah baris yang sudah ada: menaikkan penghitung, memperbaiki salah ketik, menandai pesanan sebagai sudah dikirim. Itulah UPDATE, dan pernyataan ini punya kebiasaan-kebiasaan tersendiri yang perlu dikuasai (terutama klausa WHERE). Dibahas berikutnya.

Pertanyaan yang sering diajukan

Bagaimana cara menambahkan baris di SQLite?

Gunakan INSERT INTO table (col1, col2) VALUES (val1, val2);. Menuliskan daftar kolom itu opsional, tapi sangat disarankan, karena pernyataannya tetap berfungsi meskipun nanti tabelnya mendapat kolom baru. Tanpa daftar kolom, kamu wajib memberi nilai untuk setiap kolom sesuai urutan deklarasinya.

Bagaimana cara menambahkan banyak baris sekaligus di SQLite?

Tulis beberapa tuple dalam tanda kurung setelah VALUES, dipisahkan koma: INSERT INTO t (a, b) VALUES (1, 2), (3, 4), (5, 6);. Untuk pemuatan data yang benar-benar besar (ribuan baris), bungkus semua insert dalam satu transaksi dengan BEGIN dan COMMIT. Dari situlah percepatannya datang, bukan dari sintaks banyak baris itu sendiri.

Apa fungsi INSERT OR IGNORE di SQLite?

INSERT OR IGNORE melewati baris yang akan melanggar constraint UNIQUE, PRIMARY KEY, atau NOT NULL, alih-alih memunculkan error. Baris yang bentrok dibuang diam-diam dan sisa pernyataannya tetap berjalan. Pakai ini jika kamu ingin perilaku 'insert jika belum ada' tanpa pemeriksaan keberadaan yang terpisah.

Kenapa saya mendapat error 'UNIQUE constraint failed' saat INSERT?

SQLite menemukan baris yang sudah ada dengan nilai yang sama di kolom UNIQUE atau PRIMARY KEY. Bisa jadi nilainya memang duplikat, atau kamu menjalankan ulang script seed. Ganti ke INSERT OR IGNORE untuk melewati duplikat, INSERT OR REPLACE untuk menimpanya, atau pakai ON CONFLICT ... DO UPDATE (upsert) untuk kontrol yang lebih detail.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai