SQLite w Delphi

dkacperczyk

# Wstęp

Ze względu na fakt, że nie trafiłem nigdzie w sieci na konkretny artykuł o tym, a niektórzy nie potrafią umiejętnie korzystać z dokumentacji, postanowiłem poświęcić chwilę wolnego czasu i zapoczątkować ten artykuł (bardzo proszę o uzupełnienie przez kogoś bardziej obeznanego w temacie).

# Kilka słów o SQLite

Na początek wypadałoby wyjaśnić czym właściwie jest SQLite ale uważam, że Wikipedia wyjaśni Ci to lepiej niż ja, a poza tym, jeśli czytasz ten artykuł, to za pewne trafiłeś tu nie przypadkiem a w konkretnym celu i jako takie pojęcie o tym już masz. Ja wyjaśnię tylko dlaczego warto korzystać z SQLite, konkurenta np. popularnego MySQL-a. Są to 3 główne powody:

  • SQLite nie wymaga instalowania żadnego serwera
  • SQLite nie jest wcale wolniejszy od MySQL-a
  • SQLite jest całkowicie darmowy do zastosowań komercyjnych
    i czemu nie warto (może nie tyle nie warto co są pewne utrudnienia):

Język SQL w SQLite jest uproszczony w porównaniu do innych silników bazodanowych
W SQLite nie ma praw dostępu = nie ma użytkowników
Więc zaczynajmy!

# Co jest nam potrzebne?

Więc na samym początku są nam potrzebne 3 pliki niezbędne do pisania aplikacji korzystającej z bazy danych SQLite. Pobieramy je stąd: http://www.itwriting.com/repos/sqlitewrapper/trunk/sqlitesimpledelphi.zip. Wypakowujemy archiwum i do katalogu z projektem kopiujemy pliki SQLiteTable3.pas, SQLite3.pas i SQLite3.dll (ten ostatni będziemy musieli dodatkowo skopiować do folderu z ukończonym już programem). Pliki z rozszerzeniami .pas pozwolą nam posługiwać się klasami TSQLiteDataBase oraz TSQLiteTable.

Mamy już SQLite. Teraz potrzebne jest Delphi.

Jakie Delphi? Obojętnie. Nie potrzebujemy żadnej konkretnej wersji – SQLite współpracuje z każdą wersją Delphi ponieważ jest to zwykła biblioteka. Nie będziemy musieli instalować żadnego komponentu więc możemy pisać zarówno w Personal, Enterprisse, Professional jak i w Turbo. Zacznijmy więc pisać!

# Kod aplikacji

Mamy już pustą formę. Przechodzimy do edycji kodu i w sekcji Uses dodajemy moduł SQLiteTable3. Przechodzimy do części Public klasy TForm1 i dodajemy 2 obiekty i 1 jedną zmienną:

public
SQLiteBaza: TSQLiteDataBase; //Obiekt odpowiedzialny za połączenie z bazą
SQLiteTabela: TSQLiteTable; //Obiekt odpowiedzialny za zapytania
_PATH: String; //Katalog w którym znajduje się nasza aplikacja

Obowiązki wykonaliśmy, przejdźmy do kodu OnCreate formy:

procedure TForm1.FormCreate(Sender: TObject);
begin
  SQLiteBaza := nil;
  _PATH := ExtractFilePath(Application.ExeName);
  if not FileExists(_PATH + 'baza.dat') then  //Sprawdzamy czy w katalogu z programem NIE istnieje baza danych
  begin
    SQLiteBaza := TSQLiteDataBase.Create(_PATH + 'baza.dat'); // Łączymy się z bazą
    SQLIteBaza.ExecSQL('CREATE TABLE tabela (id INTEGER PRIMARY KEY, imie VARCHAR, nazwisko VARCHAR)'); //A następnie tworzymy tabelę
  end
  else
    SQLiteBaza := TSQLiteDataBase.Create(_PATH + 'baza.dat');
end;

SQLite przechowuje całą bazę wraz z jej zawartością w jednym pliku. Jest to o tyle wygodne, że nie musimy kopiować głównego katalogu wraz z jego podkatalogami jak to ma miejsce np. w MySQL. Teraz dodamy jakieś wartości do bazy.

Wrzućmy na formę 3 Edity i Button. W OnClick Buttona piszemy tylko jedno polecenie:

SQLiteBaza.ExecSQL('INSERT INTO tabela VALUES("' + Edit1.Text + '", "' + Edit2.Text + '", "' + Edit3.Text + '")');

Nie zagnieżdżam się tu w sprawdzanie poprawności danych, które otrzymujemy od użytkownika bo to myślę, że każdy potrafi sam napisać. W tym artykule przedstawiam tylko niezbędne rzeczy.

Skoro dodaliśmy rekord do naszej tabeli to chcielibyśmy zapewne go teraz obejrzeć. Dane wyświetl w czym tylko chcesz – w Editcie, w Labelce, w tabeli StringGrid. Żeby już nie rozpisywać się to wrzuć na formę jeszcze 3 Edity i jeszcze 1 Buttona. Napisz w jego OnClick:

SQLiteTabela := SQLiteBaza.GetTable('SELECT * FROM tabela'); //Pobieramy wszystkie dane z tabeli
Edit4.Text := SQLiteTabela.FieldByName['id']; //Do jednego okienka wklejamy wartość pola id
Edit5.Text := SQLiteTabela.FieldByName['imie']; //Analogicznie
Edit6.Text := SQLiteTabela.FieldByName['nazwisko'];
SQLiteTabela.Free; //Na koniec zwalniamy pamięć

Inne polecenia wykonujemy analogicznie do np. polecenia INSERT. Teraz jeśli chcesz uruchomić aplikację na innym komputerze wystarczy, że skopiujesz aplikację i plik SQLite3.dll. Pliku z bazą nie musisz koniecznie kopiować, szczególnie, jeśli nie ma w nim żadnych danych.

Nie podaję tu przykładów użycia instrukcji UPDATE czy DELETE bo zakładam, że to już znasz. Tutaj zależało mi tylko na pokazaniu połączenia z bazą i prezentacji danych.

# Inne przydatne rzeczy

Liczba rekordów w tabeli:

SQLiteTabela.RowCount

Liczba kolumn (pól jednego rekordu):

SQLiteTabela.ColCount

Przejście do następnego rekordu (jeśli prezentujemy dane np. w tabeli StringGrid to na koniec pętli For przechodzimy do kolejnego rekordu):

SQLiteTabela.Next;

To by było chyba na tyle. Artykuł nie jest dopracowany i postanowiłem go zamieścić tylko z uwagi na dosyć spore zainteresowanie tematem w sieci. Jeśli nie uzupełni go ktoś to zrobię to ja w niedalekiej przyszłości.

Autor: Dawid Kacper Kacperczyk, [email protected]

9 komentarzy

U mnie działa. Niemniej zalecam drobne poprawki. W Powyższej wersji przy zapisywaniu rekordu musimy podać unikatowy ID a lepiej jest (przynejmniej dla mnie) kiedy program sam automatycznie ustala ID z kolejnym numerem. Wtedy zmieniamy:
w funkcji "On Create":
...
SQLIteBaza.ExecSQL('CREATE TABLE tabela (id INTEGER PRIMARY KEY AUTOINCREMENT, imie VARCHAR, nazwisko VARCHAR)'); //A następnie tworzymy tabelę

i wtedy w funkcji zapisu robimy tylko:
SQLiteBaza.ExecSQL('INSERT INTO tabela VALUES("' + Edit1.Text + '", "' + Edit2.Text + '")');
Baza zapisuje wtedy Edit1 jako Imie a Edit2 jako Nazwisko a ID sama ustala automatycznie jako wyższy.

Bardzo fajny artykuł. Krótko, jasno i na temat!

@Furious Programming nie, ponieważ Najpierw trzeba utworzyć bazę a dopiero potem wywołać ExecSQL, gdyby zaś jednak najpierw ją utworzyć [poza ifem] to ten if zawsze zwróciłby true, więc kod który proponujesz ZAWSZE utworzy nową pustą bazę. Rozwiązaniem byłoby zapisać w zmiennej to czy baza istnieje, utworzyć ją, i potem odczytać ze zmiennej czy baza istniała - jeżeli nie, wywołać execSQL

Mam pewne zastrzeżenie, poniważ kod napisany w zdarzeniu "OnCreate" formularza można skrócić; Z racji tej, że używana jest dokładnie ta sama instrukcja konstruktora warunek powinien obejmować jedynie metody "SQLIteBaza.ExecSQL()"; Jeżeli mam rację to proszę o poprawienie tej części kodu;

Jeśli chodzi o sam artykuł to dość dobry, można by jednak bardziej obszernie opisać ten temat, opierając się na wielu przykładach; Jednak to tylko wskazówka, artukuł w porządku;

Dobry, konkretny, a przede wszystkim kompletny jeżeli chodzi o podstawy SQLite pod Delphi artykuł ;]

Dziękuję.

Bardzo mi się podoba ten artykuł.
Jest tu dokładnie to czego szukałem.
Same konkrety, odnośnie połączenia i obsługi bez wdawanie się w podstawy samego Sqla.
Wielki dzięki - bardzo mi to pomogło., bo właśnie szukałem czegoś lekiego. :D

Istnieje możliwość wkompilowania sqlite do programu, przez co można rozprowadzać np. sam program i bazę czyli tylko dwa pliki.

Temat obszerny i za mało informacji...

Zrobiłem dokładnie jak w tym artykule i po otwarciu lub utworzeniu bazy poleceniem:
Baza := TSQLiteDataBase.Create(PATH + 'baza.db');
mój program się wysypuje, tj. nie działają żadne procedury w nim zawarte, np. ...Button4Click(Sender: TObject);
Dodam że zamykam baze poleceniem Baza.Free; ale tez nie działa.