SQLite komut satırı aracında satır başında nokta ile başlayan her komut, SQL değil sqlite3 programının kendisine verilen bir talimattır. .tables tabloları listeler, .schema tablo tanımlarını gösterir, .read bir dosyadaki komutları çalıştırır, .once ve .output sonuçları dosyaya yönlendirir, .dump veritabanını SQL metnine çevirir, .exit ise oturumu kapatır. Bu komutlar SQLite kütüphanesine hiç ulaşmaz; bu yüzden uygulama kodunuzda çalışmazlar.
Belgelere göre güncel araçta 60'tan fazla nokta komutu bulunur. Bu yazıda günlük işin büyük kısmını gören komutları, nokta komutlarının yazım kurallarını ve sqlite3 aracını kabuk betiklerinde kullanmayı örneklerle anlatıyoruz. Aracı henüz kurmadıysanız önce SQLite kurulumu yazısına, çıktı biçimleri için .mode çıktı biçimleri yazısına bakın. Örnekler SQLite 3.50.6 aracında betik modunda çalıştırıldı.
Nokta komutlarının kuralları

Aracın girdisi üç tür satırdan oluşur: SQL ifadeleri, nokta komutları ve araç yorumları. SQL ifadeleri serbest biçimlidir; birden çok satıra yayılabilir ve araç, sonu noktalı virgülle biten ve en az bir tam ifade içeren bir satır görene kadar metni biriktirir. Nokta komutlarının ise katı kuralları vardır:
- Nokta, satırın en solunda olmalıdır; önünde boşluk bulunamaz.
- Komutun tamamı tek satırda yer almalıdır.
- Bir SQL ifadesinin ortasında, yani devam isteminde nokta komutu yazılamaz.
- Nokta komutları için yorum söz dizimi yoktur.
- Komutun sonundaki tırnaksız noktalı virgül yok sayılır. Belgeler bunu 3.52.0, sürüm notları 3.53.0 ile verir ve olası bir uyumsuzluk olarak işaretler.
Argümanlar boşlukla ayrılır. Tek tırnak veya çift tırnak içindeki metin, içinde boşluk olsa da tek argüman sayılır ve tırnaklar atılır. \n, \t gibi C tarzı ters eğik çizgi kaçışları yalnızca çift tırnak içinde çalışır. Ayrıca satırın en solunda # ile başlayan satırlar araç yorumu olarak kabul edilir ve kütüphaneye gönderilmez. Çoğu nokta komutu kısaltılabilir; örneğin .q, .quit yerine kullanılır. Kullanılabilir komutların listesini .help, tek bir komutun ayrıntılarını .help mode gibi bir konu adıyla alırsınız.
Şemayı incelemek: .tables, .schema, .indexes, .databases
Bir veritabanı dosyasını ilk açtığınızda ne içerdiğini görmek için kullanacağınız komutlar bunlardır. Aşağıdaki örnekte iki tablo, bir indeks ve bir görünüm oluşturup her komutun ne döndürdüğüne bakıyoruz:
CREATE TABLE musteri(id INTEGER PRIMARY KEY, ad TEXT NOT NULL, sehir TEXT);
CREATE TABLE siparis(id INTEGER PRIMARY KEY, musteri_id INTEGER, tutar REAL);
CREATE INDEX siparis_musteri ON siparis(musteri_id);
CREATE VIEW buyuk_siparis AS SELECT * FROM siparis WHERE tutar > 1000;
.tables
-- çıktı: buyuk_siparis musteri siparis
.schema siparis
-- çıktı:
-- CREATE TABLE siparis(id INTEGER PRIMARY KEY, musteri_id INTEGER, tutar REAL);
-- CREATE INDEX siparis_musteri ON siparis(musteri_id);
.indexes
-- çıktı: siparis_musteri
.databases
-- çıktı: main: "" r/w.tables, tablo ve görünüm adlarını sütunlara yerleştirerek gösterir ve isteğe bağlı bir LIKE deseni alır. Belgeler bu komutun kabaca aşağıdaki sorguya denk olduğunu söyler; farkı, yalnızca ana veritabanını değil, bağlanmış (ATTACH ile eklenmiş) tüm veritabanlarını taramasıdır:
SELECT name FROM sqlite_schema
WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'
ORDER BY 1;.schema argümansız kullanıldığında bütün şemayı, bir tablo adıyla kullanıldığında o tabloya ait CREATE ifadelerini yazar; tabloya bağlı indeksler de listeye girer. --indent seçeneği uzun tanımları okunur biçimde girintiler. Yalnızca ana veritabanının şemasını görmek için .schema main.* yazabilirsiniz. .indexes indeks adlarını listeler; 3.53.0 sürüm notlarına göre bu komuta verilen desen artık indekslenen tablonun değil, indeksin adıyla eşleşir. .databases ise bağlantıdaki veritabanlarını, dosya yollarını ve okuma-yazma durumlarını gösterir; bellek içi veritabanında dosya yolu boş görünür.
.fullschema komutu şemaya ek olarak sorgu planlayıcının istatistik tablolarını da döker. Belgeler, sorgu planlayıcıyla ilgili bir sorun bildirirken bu çıktının istendiğini, ancak istatistik tablolarının gerçek veri örnekleri içerebileceği için halka açık bir kanalda paylaşılmaması gerektiğini hatırlatır. Aynı bilgilere SQL ile nasıl ulaşacağınızı SQLite tabloları listeleme yazısında bulabilirsiniz.
Oturumu yönetmek: .headers, .changes, .print, .bail
Bazı komutlar sorgunun kendisini değil, sonucun nasıl sunulacağını ve oturumun nasıl davranacağını ayarlar. .changes on her değiştirici ifadeden sonra etkilenen satır sayısını, .print verdiğiniz metni olduğu gibi yazar. .headers on sütun başlıklarını açar:
CREATE TABLE musteri(id INTEGER PRIMARY KEY, ad TEXT NOT NULL, sehir TEXT);
# Bu satır bir CLI yorumudur; SQLite kütüphanesine gönderilmez
.changes on
INSERT INTO musteri(ad, sehir) VALUES ('Ayşe', 'İzmir'), ('Mehmet', 'Ankara');
-- çıktı: changes: 2 total_changes: 2
.changes off
.headers on
SELECT ad, sehir FROM musteri ORDER BY ad;
-- çıktı:
-- ad|sehir
-- Ayşe|İzmir
-- Mehmet|Ankara
.headers off
.print Toplam müşteri:
SELECT count(*) FROM musteri;
-- çıktı:
-- Toplam müşteri:
-- 2.headers ve .separator 3.50.6 gibi eski araçlarda sık kullanılan komutlardır. 3.54 belgelerindeki .help listesinde bu iki komut artık yer almıyor; başlık ve ayırıcı gibi ayarlar .mode komutunun --titles ve --colsep seçeneklerine taşındı. Eski betiklerinizi yeni bir araçla çalıştırmadan önce bu ayrıntıyı .mode yazısında kontrol edin.
.timer on her ifadenin süresini yazar (3.51.0 ile duyarlılığı mikrosaniyeye çıktı, 3.53.0 ile .timer once yalnızca bir sonraki ifadeyi ölçer). .echo on çalıştırılan her girdiyi ekrana basar; uzun betiklerde hangi satırın hata verdiğini görmek için kullanışlıdır. Bir betiğin ilk hatada durmasını istiyorsanız .bail on kullanın:
.bail on
CREATE TABLE t(x INTEGER NOT NULL);
INSERT INTO t VALUES(1);
INSERT INTO t VALUES(NULL);
-- hata: NOT NULL constraint failed: t.x
SELECT count(*) FROM t;
-- (.bail on olduğu için bu satır hiç çalışmaz).bail kapalıyken araç hatayı standart hata akışına yazar ve sonraki satırla devam eder; aynı betik bu durumda en sonda 1 sonucunu da basardı. Her iki durumda da hata oluştuğu için araç sıfırdan farklı bir çıkış koduyla kapanır. Gerçek çıktıda hata mesajı Runtime error near line 4: ... önekiyle ve sonunda hata kodu olan (19) ile görünür. Hata kodlarının anlamı için SQLite hata kodları yazısına bakın.
Dosyalarla çalışmak: .open, .read, .output, .once

.open, önce mevcut bağlantıyı kapatır, sonra verilen dosyayı açar. :memory: adı yeni bir bellek içi veritabanı, ad verilmemesi ise kapanınca silinen geçici bir disk veritabanı açar. Seçenekleri dikkatle kullanın: --new var olan veriyi onay sormadan siler, --readonly yazmayı engeller, --ifexists (3.51.0 ve sonrası) dosya yoksa yenisini oluşturmaz, --deserialize dosyanın tamamını belleğe okur ve değişiklikleri siz .save ya da .backup ile yazmadıkça diske geri koymaz.
.read DOSYA, klavyeden okumayı geçici olarak bırakıp girdiyi dosyadan alır; dosya bitince klavyeye döner. Dosyada nokta komutları da bulunabilir. Argüman | ile başlıyorsa geri kalanı bir komut olarak çalıştırılır ve o komutun çıktısı girdi olarak kullanılır; SQL üreten bir betiği doğrudan çalıştırmanın yolu budur. Çıktı tarafında .output DOSYA sonraki bütün sonuçları dosyaya yazar, argümansız .output ekrana döner. .once DOSYA ise yalnızca bir sonraki komutun çıktısını yönlendirir:
.once rapor.txt
SELECT ad FROM musteri;
SELECT 'bu satır ekrana gelir';
-- çıktı: bu satır ekrana gelir
.output tum.txt
SELECT 1;
SELECT 2;
.output
SELECT 'yeniden ekran';
-- çıktı: yeniden ekran
-- rapor.txt içeriği: Ayşe ve Mehmet (iki satır)
-- tum.txt içeriği: 1 ve 2 (iki satır)Dosya adı yerine | ile başlayan bir komut verirseniz çıktı o komuta borulanır. -e seçeneği çıktıyı geçici bir dosyada toplayıp sistemin metin düzenleyicisini, -x seçeneği CSV olarak toplayıp elektronik tablo programını, -w seçeneği ise web tarayıcısını açar. .excel komutu .once -x, .www komutu .once -w ile aynı işi yapar. CSV dışa ve içe aktarmanın ayrıntıları SQLite CSV içe ve dışa aktarma yazısında.
Veritabanını metne dökmek: .dump
.dump, veritabanının tamamını ya da verdiğiniz nesneleri, yeniden çalıştırıldığında aynı içeriği üreten UTF-8 SQL metnine çevirir. Aşağıdaki çıktıda görüldüğü gibi döküm, yabancı anahtar denetimini kapatan bir pragma ile başlar ve bütün ifadeleri tek bir işlem bloğu içine koyar:
-- kur.sql dosyası:
-- CREATE TABLE urun(id INTEGER PRIMARY KEY, ad TEXT, fiyat REAL);
-- INSERT INTO urun(ad, fiyat) VALUES ('Kalem', 12.5), ('Defter', 40);
.read kur.sql
SELECT count(*) FROM urun;
-- çıktı: 2
.dump urun
-- çıktı:
-- PRAGMA foreign_keys=OFF;
-- BEGIN TRANSACTION;
-- CREATE TABLE urun(id INTEGER PRIMARY KEY, ad TEXT, fiyat REAL);
-- INSERT INTO urun VALUES(1,'Kalem',12.5);
-- INSERT INTO urun VALUES(2,'Defter',40.0);
-- COMMIT;Belgeler bu çıktıyı arşivlik bir kopya almanın iyi bir yolu olarak önerir. Metin saf SQL olduğu için başka bir veritabanı motoruna aktarmak için de kullanılabilir, ancak sütun tipleri ve SQLite'a özgü söz dizimi hedef sistemde düzenleme gerektirebilir. Çıktıyı sıkıştırıp başka bir makinede geri yüklemek şöyle yapılır:
sqlite3 app.db .dump | gzip -c > app.dump.gz
zcat app.dump.gz | sqlite3 yeni.db.dump mantıksal bir dökümdür ve bozuk bir dosyada ilk bozulma belirtisinde durur. Bozuk dosyalardan veri kurtarmak için tasarlanan .recover komutunu bozuk veritabanı kurtarma yazısında, çalışan bir veritabanının tutarlı kopyasını almak için .backup ve VACUUM INTO yöntemlerini yedekleme yazısında anlatıyoruz.
Parametreler ve diğer yararlı komutlar
SQL metninde ?, ?NNN, :ad, @ad ve $ad biçiminde parametreler kullanabilirsiniz. Araç, adsız ? parametrelerini bağlamaz ve bunlar NULL olur. Adlı parametrelere ise temp.sqlite_parameters tablosundan değer atanır; bu tabloyu .parameter komutu yönetir. Belgelere göre değer önce bir SQL ifadesi olarak değerlendirilir; metin istediğinizde değeri tek tırnak içine alıp dışını çift tırnakla korumanız gerekir, örneğin .parameter set @tel "'202-456-1111'". Aksi hâlde bu ifade bir çıkarma işlemi olarak hesaplanır.
.read kur.sql
.parameter init
.parameter set :enfazla 20
SELECT ad FROM urun WHERE fiyat <= :enfazla;
-- çıktı: Kalem
.parameter list
-- çıktı: :enfazla 20Bu mekanizma yalnızca komut satırı aracına özgüdür; uygulamalar parametreleri kendi bağlayıcılarının bağlama fonksiyonlarıyla verir. Parametreli sorguların güvenlik açısından önemi için SQL injection önleme yazısına bakabilirsiniz. Diğer yararlı komutlar arasında .shell ve .system (işletim sistemi komutu çalıştırır), .connection (3.37.0 ile gelen, en fazla on ayrı bağlantı arasında geçiş), .timeout MS (kilitli tabloları belirtilen süre boyunca yeniden dener) ve .exit KOD (verilen çıkış koduyla kapanır) sayılabilir.
Uygulamalı örnek: tanımadığınız bir veritabanını incelemek
Bir sunucuda size teslim edilen ve içeriğini bilmediğiniz bir veritabanı dosyasını incelerken, yanlışlıkla değişiklik yapmamak için aracı salt okunur başlatmak iyi bir başlangıçtır. Ardından hangi dosyanın açık olduğunu, hangi tabloların bulunduğunu ve bir tablonun yapısını sırayla kontrol eder, son olarak tek bir kaydı line biçiminde okursunuz. Aşağıdaki oturum, yukarıdaki müşteri ve sipariş tablolarını içeren bir dosyada çalıştırıldı (dosya yolu kısaltıldı):
sqlite3 -readonly app.db
.databases
-- çıktı: main: /yol/app.db r/o
.tables
-- çıktı: buyuk_siparis musteri siparis
.schema --indent musteri
-- çıktı: CREATE TABLE musteri(id INTEGER PRIMARY KEY, ad TEXT NOT NULL, sehir TEXT);
SELECT count(*) FROM musteri;
-- çıktı: 2
.mode line
SELECT * FROM musteri LIMIT 1;
-- çıktı:
-- id = 1
-- ad = Ayşe
-- sehir = İzmir.databases çıktısının sonundaki r/o, dosyanın gerçekten salt okunur açıldığını doğrular. Kısa tanımlar --indent ile değişmeden kalır; seçenek asıl farkını onlarca sütunlu uzun tablolarda gösterir. Line biçimi, sütun sayısı fazla olan tablolarda tek kaydı okumanın en rahat yoludur. İnceleme bittikten sonra değişiklik yapmanız gerekirse aracı -readonly olmadan yeniden açın.
Kabuk betiklerinde sqlite3 kullanmak
Betiklerde iki yaygın yöntem vardır. Birincisi, komutları bir dosyada veya heredoc içinde toplayıp aracın standart girişine vermektir. İkincisi, dosya adından sonra tek bir SQL komutunu argüman olarak yazmaktır; bu durumda sonuç list biçiminde standart çıktıya basılır ve araç kapanır. Bu ikinci yöntem, sonucu bir kabuk değişkenine almak veya awk gibi araçlara aktarmak için tasarlanmıştır:
#!/bin/sh
sqlite3 app.db <<'SQL'
CREATE TABLE IF NOT EXISTS kayit(id INTEGER PRIMARY KEY, mesaj TEXT);
INSERT INTO kayit(mesaj) VALUES ('yedek basladi');
SELECT count(*) FROM kayit;
SQL
# çıktı: 1
sayi=$(sqlite3 app.db "SELECT count(*) FROM kayit;")
echo "Kayit sayisi: $sayi"
# çıktı: Kayit sayisi: 1Standart giriş ve çıktı bir dosyaya veya boruya bağlıyken araç betik (batch) modunda çalışır ve eski list biçimini kullanır; bu yüzden betik çıktılarınız yeni sürümlerde de ayrıştırılabilir kalır. Heredoc sınırlayıcısını tek tırnak içine almak, kabuğun $ ile başlayan SQL parametrelerini değişken sanıp genişletmesini önler. Hata durumunda sıfırdan farklı çıkış kodu döndüğü için betiğinizde bu kodu kontrol edebilirsiniz.
Sık yapılan hatalar

- Nokta komutunu girintilemek: Önünde boşluk olan bir nokta komutu SQL sanılır ve söz dizimi hatası verir.
- Nokta komutunu uygulama kodunda denemek:
.tablesgibi komutlar bağlayıcılarda çalışmaz; aynı bilgiyisqlite_schematablosundan sorgulayın. - SQL ifadesinin ortasına nokta komutu yazmak: Noktalı virgülü unuttuğunuz bir ifadenin devam satırında yazılan nokta komutu, ifadenin parçası olarak yorumlanır.
- .output'u kapatmayı unutmak: Argümansız
.outputvermezseniz sonraki bütün sonuçlar dosyaya gitmeye devam eder; tek seferlik yönlendirme için.oncedaha güvenlidir. - .open --new ile veriyi silmek: Bu seçenek var olan dosyanın içeriğini onay istemeden yok eder.
Sık Sorulan Sorular
Nokta komutlarının tam listesini nereden görebilirim?
Kullandığınız sürümde .help komutunu çalıştırın. Liste sürümden sürüme ve derleme seçeneklerine göre değişir; belgeler ayrıca test amaçlı belgelenmemiş ve geriye uyumluluk için tutulan eski komutların bulunduğunu belirtir.
.tables neden bir tabloyu göstermiyor?
Genellikle yanlış dosyayı açmışsınızdır; var olmayan bir dosya adı yeni ve boş bir veritabanı oluşturur. .databases ile hangi dosyanın açık olduğunu kontrol edin. Ayrıca sqlite_ ile başlayan iç tablolar listeye alınmaz.
Bir betiği oturum içinden nasıl çalıştırırım?
.read betik.sql yazın. Betik bitince araç tekrar klavyeden girdi beklemeye döner.
.dump çıktısı yedek yerine geçer mi?
Küçük veritabanları ve başka bir motora aktarım için kullanışlıdır, ancak canlı ve büyük veritabanlarında .backup veya VACUUM INTO daha uygundur. Yöntemlerin karşılaştırması yedekleme yazısında.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: SQLite öğrenme rehberi · SQLite kurulumu · SQLite .mode çıktı biçimleri · SQLite CSV içe ve dışa aktarma · SQLite tabloları listeleme