INSERT ile Tabloya Satır Ekleme
SQLite'ta yeni satır eklemek için kullandığınız komut INSERT. Yapısı kısa ve tahmin edilebilir:
Dikkat etmeniz gereken üç kısım var:
INSERT INTO books— hedef tablo.(title, author, year)— değer vereceğin sütunlar.VALUES (...)— sütun sırasıyla aynı sırada gelen değerler.
id sütun listesinde yok, çünkü SQLite onu otomatik olarak atıyor (INTEGER PRIMARY KEY olduğu için rowid değerini alıyor). Listeye yazmadığınız her sütun varsayılan değerine düşer; varsayılan tanımlı değilse NULL olur.
Sütunları Her Zaman Açıkça Yaz
Sütun listesini atlayıp tüm sütunlara tanımlandıkları sırayla değer vermek mümkün:
-- Çalışır, ancak kırılgandır:
INSERT INTO books VALUES (NULL, 'Dune', 'Frank Herbert', 1965);
Sapma. books tablosuna biri yeni bir kolon eklediği an, bu şekilde yazılmış her ifade ya patlar ya da değerleri yanlış kolonlara yazmaya başlar. Kolonları açık açık yazın:
Sütun isimlerini açıkça yazmak bir tür dokümantasyon görevi görür — sorguyu okuyan kişi tablo tanımına bakmaya ihtiyaç duymadan ne olup bittiğini anlar.
SQLite ile çoklu satır ekleme
Tek bir INSERT ifadesinde birden fazla değer kümesi yazarak aynı anda birkaç satırı birden ekleyebilirsiniz:
Bu yaklaşım, üç ayrı INSERT cümlesinden çok daha temiz duruyor ve SQLite hepsini tek bir ifade olarak işliyor. Ama toplu veri yüklemede asıl performans farkını yaratan şey, insert'leri bir transaction içine almak — birazdan ona da geleceğiz.
SQLite toplu insert: işlemi transaction'a sarın
SQLite varsayılan olarak her INSERT cümlesini ayrı bir transaction olarak çalıştırır. Her birinin sonunda bir fsync yapar; klasik döngü içindeki insert'leri yavaşlatan da zaten bu — insert'in kendisi değil.
Hepsini tek seferde gruplayın:
Beş fsync yerine bir tane. Binlerce satırda bu fark iki, hatta üç kat büyüklüğe ulaşabiliyor. Arada bir şey ters giderse ROLLBACK tüm partiyi geri alıyor.
Bu kalıp, sqlite toplu insert işinin klasik reçetesidir. SQLite'ı Python'dan mı çağırıyorsunuz, Node'dan mı, Rust'tan mı — fark etmez; döngünüzü BEGIN / COMMIT arasına alın yeter.
INSERT ... SELECT: Başka Bir Tablodan Veri Kopyalamak
Bir tabloyu sabit değerler yerine bir sorgunun sonucundan da doldurabilirsiniz; buna sqlite insert select deniyor:
SELECT ifadesinden gelen sütunlar, INSERT cümlesindeki sütun listesine sıraya göre eşleştirilir. İsimlerin uyuşması şart değil — önemli olan sıra. Bu yaklaşım; satırları arşivlemek, raporlama tabloları oluşturmak veya bir migration sırasında verinin bir kısmını kopyalamak için standart yöntemdir.
DEFAULT VALUES ve Atlanan Sütunlar
Bir sütunda DEFAULT tanımı varsa, onu sütun listesinden çıkarabilirsiniz; SQLite varsayılan değeri kendisi yerleştirir:
created_at sütunu, biz değer vermediğimiz için otomatik olarak şu anki zaman damgasını alır. Tamamen varsayılan değerlerden oluşan bir satır eklemek istiyorsanız — mesela placeholder satırlar oluştururken işine yarar — DEFAULT VALUES biçimini kullanabilirsiniz:
İki yeni satır eklendi; ikisinin de value değeri 0 ve id'leri otomatik atandı.
INSERT OR IGNORE: Yinelenen kayıtları atlama
Eklenmek istenen bir satır UNIQUE veya PRIMARY KEY kısıtlamasını ihlal ederse, varsayılan davranış işlemi durdurup hata fırlatmaktır:
Error: UNIQUE constraint failed: users.email
INSERT OR IGNORE ise bu davranışı değiştirir; çakışan satırı sessizce atlar:
Üç satır hayatta kalır. Tekrar eden kayıt sessizce, hata vermeden atlanır. Basit seed verisi için "kayıt yoksa ekle" mantığını ifade etmenin SQLite'a özgü, deyimsel yolu budur — önce ayrı bir SELECT ile kontrol etmeye veya exception yakalamaya gerek kalmadan.
INSERT OR REPLACE: Mevcut Kaydın Üzerine Yazma
INSERT OR REPLACE, çakışan satırı silip yerine yenisini ekler:
Dikkat etmeniz gereken bir nokta var: REPLACE aslında DELETE + INSERT demek, UPDATE değil. Silinen satıra ON DELETE CASCADE ile bağlı foreign key'ler varsa, çocuk kayıtlar da silinir. Ayrıca yeni INSERT sırasında belirtmediğiniz kolonlar eski değerini korumaz; varsayılan değerine döner.
"Varsa güncelle, yoksa ekle" senaryolarının çoğunda aslında istediğiniz şey gerçek bir upsert: yani ON CONFLICT ... DO UPDATE. Onu da ayrı bir sayfada ele alıyoruz.
Kısa bir özet
INSERT INTO tablo (kolonlar) VALUES (...)— temel kullanım. Kolonları her zaman açıkça yaz.- Çoklu satır ekleme için
VALUES'tan sonra virgülle ayrılmış demetler kullanılır. - Gerçek toplu insert işlemlerinde sorguları
BEGIN/COMMITarasına al. INSERT INTO ... SELECT ...bir sorgudan gelen satırları kopyalar.DEFAULT VALUESsadece varsayılan değerlerle satır oluşturur; atladığınız kolonlar da varsayılana düşer.INSERT OR IGNOREçakışan satırları atlar;INSERT OR REPLACEise onları üzerine yazar (sil + ekle yöntemiyle).
Sırada: UPDATE
Satır eklemek işin yarısı. Diğer yarısı ise mevcut satırları değiştirmek — bir sayacı artırmak, yazım hatasını düzeltmek, siparişi "kargolandı" olarak işaretlemek. Bunun için UPDATE var ve doğru kullanmak için bilmeniz gereken kendine has alışkanlıkları var (özellikle de WHERE koşulu konusunda). Sırada o var.
Sıkça Sorulan Sorular
SQLite'ta tek bir satırı nasıl eklerim?
Temel yapı şu: INSERT INTO tablo (kolon1, kolon2) VALUES (deger1, deger2);. Kolon listesi yazmak zorunlu değil ama şiddetle tavsiye ederim — ileride tabloya yeni bir kolon eklendiğinde sorgunuz çalışmaya devam eder. Kolon listesi yazmazsanız, tüm kolonlar için tanımlandıkları sırayla değer vermeniz gerekir.
SQLite'ta birden fazla satır tek seferde nasıl eklenir?
VALUES kısmından sonra parantezli demetleri virgülle ayırarak art arda yazın: INSERT INTO t (a, b) VALUES (1, 2), (3, 4), (5, 6);. Binlerce satırlık gerçek toplu yüklemelerde ise asıl hız kazancı çoklu satır sözdiziminden değil, insert'leri BEGIN ve COMMIT ile tek bir transaction içine almaktan gelir.
INSERT OR IGNORE ne işe yarar?
INSERT OR IGNORE, UNIQUE, PRIMARY KEY veya NOT NULL kısıtını ihlal edecek satırları hata fırlatmak yerine sessizce atlar. Çakışan satır geçilir, sorgunun geri kalanı çalışmaya devam eder. "Zaten varsa ekleme" davranışını ayrı bir kontrol sorgusu yazmadan istediğinizde tam aradığınız şey budur.
INSERT yaparken neden 'UNIQUE constraint failed' hatası alıyorum?
SQLite, UNIQUE veya PRIMARY KEY kolonunda aynı değere sahip bir satır bulmuş demektir. Ya değer gerçekten tekrar eden bir kayıt, ya da seed scriptini ikinci kez çalıştırıyorsunuz. Yinelenenleri atlamak için INSERT OR IGNORE, üzerine yazmak için INSERT OR REPLACE veya daha kontrollü bir upsert için ON CONFLICT ... DO UPDATE kullanabilirsiniz.