SQLITE3 MIT DELPHI XE3 … aus der Praxis für die Praxis … Robert W.B. Linn, Jahrgang 1958, befasst sich seit Mitte der 80er mit Delphi, damals noch auf DOS Basis mit Turbo Pascal, dann mit Turbo Delphi und aktuell mit Delphi XE3. Impressum Copyright: © 2013 Robert W.B. Linn, Pinneberg, Germany. Internet: http://www.rwblinn.de Druck und Verlag: Kein ISBN: Kein 1. Auflage 2013 Der Autor übernimmt keine Garantie und Haftung für eventuelle Fehler im Text und den Beispielen. Diesbezügliche Hinweise werden gerne entgegengenommen. Sollten Informationen (Texte und Grafiken) nicht auf dem neuesten Stand sein, wird hierfür keine Haftung übernommen. SQLite ist Public Domain. Die Marke SQLite ist beim United States Patent and Trademark Office registriert. Delphi ist ein eingetragenes Warenzeichen von Embarcadero Technologies Microsoft und Windows sind eingetragene Warenzeichen von Microsoft Corporation in den USA und anderen Ländern. Die Bezeichnungen „Java" und „JavaScript" sind Warenzeichen oder eingetragene Warenzeichen von Sun Microsystems, Inc. Andere verwendete Markennamen sind eingetragene Warenzeichen der jeweiligen Firmen und/oder Privatpersonen. SQLite3 mit Delphi XE3 03.09.2013 Inhaltsverzeichnis Inhaltsverzeichnis .................................................................................................................................... 2 Einleitung ................................................................................................................................................. 4 Information.......................................................................................................................................... 4 SQLite Datentypen („Storage Classes“) ............................................................................................... 4 Schema Beispieldatenbank ................................................................................................................. 5 Schnelleinstieg ......................................................................................................................................... 6 SQLite Datenbank und Tabelle erstellen ............................................................................................. 6 SQLite Datenbank Tabellenliste im TMemo ........................................................................................ 6 SQLite Datenbank Datensätze im TMemo .......................................................................................... 8 SQLite Datenbank Datensätze im TStringGrid..................................................................................... 9 SQLite Datenbank Datensätze im DBGrid (Direkt) ............................................................................ 10 SQLite Datenbank Datensätze im DBGrid (Aktionen) ....................................................................... 11 SQLConnection ...................................................................................................................................... 12 SQLConnection Vorbereiten .............................................................................................................. 12 SQLConnection Eigenschaften........................................................................................................... 12 SQLConnection Verbindung öffnen ................................................................................................... 13 SQL-Befehle ........................................................................................................................................... 14 SQL-Befehle ausführen - SQLConnection .......................................................................................... 14 SQL-Befehle ausführen - SQLDataSet ................................................................................................ 15 SQL-Befehl Beispiele .......................................................................................................................... 16 CREATE TABLE Tabelle (Spalte1 Typ, SpalteN Typ) ........................................................................... 16 INSERT INTO Tabelle (Spalte1, SpalteN) VALUES (Wert1, WertN) .................................................... 17 INSERT INTO Tabelle (Spalte1, SpalteN) VALUES (:Spalte1, :SpalteN) .............................................. 18 SELECT Spalten FROM Tabelle(n) WHERE Bedingung ORDER BY Sortierung GROUP BY Gruppierung HAVING Einschränkung ..................................................................................................................... 19 UPDATE Tabelle SET Spalte1=Wert, SpalteN=Wert WHERE Spalte=Bedingung ............................... 20 DELETE FROM TABLE WHERE Spalte=Bedingung .............................................................................. 20 DROP TABLE Tabellenname ............................................................................................................... 20 CREATE INDEX Indexname ON Tabelle(Spalte) ................................................................................. 20 DROP INDEX Indexname.................................................................................................................... 20 VIEWS .................................................................................................................................................... 21 CREATE VIEW Name AS SELECT Befehl.............................................................................................. 21 DROP VIEW Viewname ...................................................................................................................... 21 TRIGGER................................................................................................................................................. 22 CREATE TRIGGER Name AFTER Aktion ON Tabelle BEGIN Ereignis; END .......................................... 22 Tabelle Log erstellen...................................................................................................................... 22 Trigger erstellen ............................................................................................................................ 23 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 2- SQLite3 mit Delphi XE3 03.09.2013 PRAGMA ................................................................................................................................................ 24 PRAGMA database_list ...................................................................................................................... 24 PRAGMA table_info (Tabellenname) ................................................................................................ 24 PRAGMA index_list (Tabellenname) ................................................................................................. 25 PRAGMA index_info (Indexname) ..................................................................................................... 25 PRAGMA auto_vacuum ..................................................................................................................... 25 PRAGMA integrity_check .................................................................................................................. 25 SQLite SELECT Beispiele......................................................................................................................... 26 SELECT ausführen .............................................................................................................................. 26 SELECT Ergebnis im StringGrid darstellen ......................................................................................... 27 SELECT Ergebnis TLabel und TEdit zuweisen ..................................................................................... 28 SELECT Ergebnis TStringList und TListBox zuweisen ......................................................................... 28 SELECT Ergebnis in HTML Tabelle ausgeben ..................................................................................... 29 SELECT auf mehrere Tabellen (JOIN) ................................................................................................. 30 SELECT sqlite_master ........................................................................................................................ 31 SELECT CAST ( Ausdruck AS Datentyp [ ( Länge ) ] ) .......................................................................... 31 SQLite und FireDAC Einstieg .................................................................................................................. 32 SQLite spezielle Anwendungsbeispiele ................................................................................................. 33 SQLite Datensätze im DBGRID ........................................................................................................... 33 SQLite BLOBs verwenden .................................................................................................................. 36 SQLite SQL-Befehle direkt ausführen ................................................................................................ 38 SQLite Tabelle für Einstellungen verwenden .................................................................................... 39 Anhang .................................................................................................................................................. 41 Fehlermeldungen und Abhilfe (unvollständige Liste!) ...................................................................... 41 Zusammenfassung einige SQL-Befehle (Beispiele)............................................................................ 42 Referenz Beispieldatenbank Buecher.db SQL-Befehle..................................................................... 43 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 3- SQLite3 mit Delphi XE3 03.09.2013 Einleitung Die vorliegende Anleitung vermittelt den praxisnahen Umgang mit SQLite3 unter Embarcadero Delphi XE3. Ziel ist es anhand Beispiele die direkte Anwendung zu zeigen. SQLite ist ein relationales Datenbanksystem, welches SQL-92-Standard festgelegten SQLSprachbefehle weitgehend unterstützt. SQLite wird in allen Bereiche eingesetzt und ist als Datenbank nicht mehr wegzudenken. SQLite ist Public Domain. Information Information SQLite im Internet unter SQLite Org Zur Anleitung verschiedene Projektbeispiele mit Quellcode Delphi XE3: o SQLite DBGrid verwenden (ropDelphiSQLiteDBGrid) o SQLite Blobs verwenden (ropDelphiSQLiteBlob) o SQLite SQL-Befehle direkt ausführen (ropSQLiteIt) o Mini Buecherverwaltung (ropBookLib) SQLite Datentypen („Storage Classes“) Datentyp NULL INTEGER TEXT BLOB REAL Wert NULL Eine Ganzzahl, gespeichert in 1, 2, 3, 4, 6, oder 8 Byte je nach Größe des Wertes (signed 64-bit) Ein String, gespeichert unter Verwendung der DatenbankKodierung (UTF-8, UTF-16BE oder UTF-16LE) (Max Grösse Vorgabe 1,000,000,000 bytes) Eine Masse von Daten, gespeichert wie eingegeben Eine Fließkommazahl gespeichert als IEEE Gleitkommazahl von 8 Byte (64-bit (double)) NUMERIC (Priorität) Typ-Affinität (1) INT, INTEGER, TINYINT, SMALLINT, MEDIUMINT, BIGINT, UNSIGNED BIG INT, INT2, INT8, FLOATING POINT (2) CHARACTER(20), VARCHAR(255), VARYING CHARACTER(255), NCHAR(55), NATIVE CHARACTER(70), NVARCHAR(100), TEXT, CLOB (3) BLOB (4) REAL, DOUBLE, DOUBLE PRECISION, FLOAT (5) NUMERIC, DECIMAL(10,5), BOOLEAN, DATE, DATETIME, STRING HINWEIS Die Typ-Affinität einer Spalte ist der empfohlene Datentyp für in dieser Spalte gespeicherte Daten. © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 4- SQLite3 mit Delphi XE3 03.09.2013 Schema Beispieldatenbank Für diese Anleitung wird die Datenbank BUECHER.DB bestehend aus den 3 Tabellen Buecher, Autoren, Log verwendet. Abbildung 1 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 5- SQLite3 mit Delphi XE3 03.09.2013 Schnelleinstieg SQLite Datenbank und Tabelle erstellen Eine neue SQLite Datenbank Buecher.db mit Tabelle Buecher erstellen. Aktivität Delphi Projekt erstellen oder öffnen, Form wählen TSQLConnection Komponente hinzufügen Variable definieren SQLite Datenbank erstellen Beschreibung Vgl. frmMain TSQLConnection (dbExpress). Eigenschaften anpassen: Name: SQLConnection; Driver=SQLite; LoginPrompt=False Var FSQLCommandText: String; FSQLDataSet: TDataSet; sStr: String; i: Integer; Try SQLConnection.Connected := False; SQLConnection.Params.Values['Database']:='<Pfad>\Buecher.db'; SQLConnection.Params.Values['FailIfMissing'] := 'False'; SQLConnection.Connected := True; Except On E: EDatabaseError Do ShowMessage(E.Message); End; Tabelle hinzufügen Try FSQLCommandText := 'CREATE TABLE Buecher (BuchID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,Titel VARCHAR(100) NOT NULL,AutorID INTEGER,ISBN VARCHAR(20));'; SQLConnection.ExecuteDirect(FSQLCommandText); Except On E: EDatabaseError Do ShowMessage(E.Message); End; Testdaten hinzufügen Try FSQLCommandText := 'INSERT INTO Buecher (BuchID,Titel,AutorID,ISBN) VALUES (NULL,"B1",1,"123");'; SQLConnection.ExecuteDirect(FSQLCommandText); FSQLCommandText := 'INSERT INTO Buecher (BuchID,Titel,AutorID,ISBN) VALUES (NULL,"B2",1,"456");'; SQLConnection.ExecuteDirect(FSQLCommandText); Except On E: EDatabaseError Do ShowMessage(E.Message); End; Testdaten zeigen Try FSQLCommandText := 'SELECT * FROM Buecher;'; SQLConnection.Execute(FSQLCommandText, NIL, FSQLDataSet); FSQLDataSet.First; While NOT FSQLDataSet.EOF Do Begin sStr := ''; For i := 0 To FSQLDataSet.FieldCount - 1 Do sStr := sStr + ' ' + FSQLDataSet.Fields[i].AsString; ShowMessage(sStr); FSQLDataSet.Next; End; Except On E: EDatabaseError Do ShowMessage(E.Message); End; SQLite Datenbank Tabellenliste im TMemo © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 6- SQLite3 mit Delphi XE3 Aktivität Delphi Projekt erstellen oder öffnen, Form wählen Komponenten hinzufügen Procedure FormCreate erstellen/anpassen 03.09.2013 Beschreibung Vgl. frmMain TSQLConnection (dbExpress). Eigenschaften anpassen: Name: SQLConnection; Driver=SQLite; LoginPrompt=False TMemo (Standard). Eigenschaften anpassen: Name: memoOutput; ScrollBars: ssBoth; WordWrap: False; SQLConnection Pfad zur bestehenden SQLite Datenbank Buecher.db setzen und verbinden. Ist die Datenbank nicht vorhanden, dann Abbruch. Try SQLConnection.Connected := False; SQLConnection.Params.Values['Database']:='<SQLiteDBPfad>'; SQLConnection.Params.Values['FailIfMissing']:='True'; SQLConnection.Connected := True; Except On E: EDatabaseError Do ShowMessage(E.Message); End; Procedure FormCreate erweitern Datenbank ist geöffnet, Tabellenliste im TMemo ausgeben: Var FSQLCommandText: String; FSQLDataSet: TDataSet; sLine: String; i: Integer; Try memoOutput.Lines.Text := 'Tabellen:'; FSQLCommandText := 'SELECT name FROM SQLITE_MASTER WHERE TYPE="table" ORDER BY name;'; SQLConnection.Execute(FSQLCommandText, NIL, FSQLDataSet); FSQLDataSet.First; While NOT FSQLDataSet.EOF Do Begin sLine := ''; For i := 0 To FSQLDataSet.FieldCount - 1 Do sLine := sLine + FSQLDataSet.Fields[i].AsString; memoOutput.Lines.Add(sLine); FSQLDataSet.Next; End; Except On E: EDatabaseError Do ShowMessage(E.Message); End; Inhalt TMemo Ergebnis SQL-Abfrage: SELECT name FROM SQLITE_MASTER WHERE TYPE="table" ORDER BY name; Abbildung 2 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 7- SQLite3 mit Delphi XE3 03.09.2013 SQLite Datenbank Datensätze im TMemo Aktivität SQLite Datenbank öffnen SQL-Abfrage ausführen und Ergebnis speichern (TDataSet) Beschreibung Siehe vorher. Var FSQLCommandText: String; FSQLDataSet: TDataSet; FSQLCommandText := 'SELECT * FROM Autoren;'; SQLConnection.Execute(FSQLCommandText, NIL, FSQLDataSet); Datensätze im TMemo zeigen Var FSQLCommandText: String; FSQLDataSet: TDataSet; sLine: String; i: Integer; memoSQLiteDBQueryResult.Lines.Text := 'Anzahl Datensätze: ' + IntToStr(FSQLDataSet.RecordCount); // Spaltennamen sLine := ''; For i := 0 To FSQLDataSet.FieldCount - 1 Do sLine := sLine + ' ' + FSQLDataSet.Fields[i].FieldName; memoSQLiteDBQueryResult.Lines.Add(sLine); memoSQLiteDBQueryResult.Lines.Add('----------'); // Inhalt FSQLDataSet.First; While NOT FSQLDataSet.EOF Do Begin sLine := ''; For i := 0 To FSQLDataSet.FieldCount - 1 D sLine := sLine + ' ' + FSQLDataSet.Fields[i].AsString; memoSQLiteDBQueryResult.Lines.Add(sLine); FSQLDataSet.Next; End; Inhalt TMemo Ergebnis SQL-Abfrage: SELECT * FROM Autoren Abbildung 3 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 8- SQLite3 mit Delphi XE3 03.09.2013 SQLite Datenbank Datensätze im TStringGrid Aktivität SQLite Datenbank öffnen Form TStringGrid Komponente hinzufügen SQL-Abfrage ausführen Beschreibung Siehe vorher. TStringGrid (Additional). Eigenschaften anpassen: Name sgSQLiteDBQueryToStringGrid Options: [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goRowSelect] Var FSQLCommandText: String; FSQLDataSet: TDataSet; FSQLCommandText := 'SELECT * FROM Autoren;'; SQLConnection.Execute(FSQLCommandText, NIL, FSQLDataSet); Datensätze lesen und im StringGrid anzeigen If FSQLDataSet.IsEmpty Then Exit; StringGrid1.ColCount := FSQLDataSet.FieldCount + 1; StringGrid1.RowCount := FSQLDataSet.RecordCount + 1; StringGrid1.FixedCols := 1; StringGrid1.FixedRows := 1; StringGrid1.ColWidths[0] := 16; //Fixspalte Breite anpassen // Spaltenüberschriften setzen For nCol := 0 To FSQLDataSet.FieldCount - 1 Do StringGrid1.Cells[nCol + 1, 0] := FSQLDataSet.Fields[nCol].FieldName; nLin := 0; // Daten im Stringgrid zeigen FSQLDataSet.First; While Not FSQLDataSet.Eof Do Begin For nCol := 0 To FSQLDataSet.FieldCount - 1 Do StringGrid1.Cells[nCol+1,nLin + StringGrid1.FixedRows]:= FSQLDataSet.Fields[nCol].AsString; FSQLDataSet.Next; Inc(nLin); End; Inhalt TStringGrid Abbildung 4 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 9- SQLite3 mit Delphi XE3 03.09.2013 SQLite Datenbank Datensätze im DBGrid (Direkt) Eine vorhandene SQLite Datenbank öffnen und die Datensätze in einem DBGrid zeigen. Aktivität Verzeichnis für ein neues Delphi Projekt erstellen Dateien in das neue Verzeichnis kopieren Delphi neues Projekt erstellen Projekt Eigenschaften anpassen Beschreibung Vgl. Buecher DLL sqlite3.dll (oder in das Windows System Verzeichnis kopieren) Eine bestehende Datenbank kopieren. Vgl. buecher.db File > New > VCL Forms Application Delphi Project > Options > Delphi Compiler Target: Release Configuration; Output Directory: Leeren Eintrag; Unit Output Directory: Leeren Eintrag Form Form1 Eigenschaften Name: frmMain; Caption: Bücherliste; Position: poDesktopCenter anpassen In Form frmMain TSQLConnection (dbExpress) -> TSQLDataSet (dbExpress) -> Komponenten hinzufügen TDataSetProvider (Data Access)-> ClientDataSet (Data Access)-> verbinden und anpassen TDataSource (Data Access) -> TDBGrid (Data Controls) TSQLConnection Name: SQLConnection; Driver=SQLite; LoginPrompt=False; Params: FailIfMissing=False, Database=buecher.db; Connected=True TSQLDataset Name: SQLDataSet; Connection: SQLConnection; Und CommandText=SELECT * FROM Buecher; SQL-Befehl definieren CommandType=ctQuery; Active=True TDataSetProvider Name=DataSetProvider; Dataset=SQLDataSet TClientDataSet Name=ClientDataset ; Providername=DataSetProvider; Active=True TDataSource Name=DataSource; DataSet=ClientDataSet TDBGrid Name=DBGrid; DataSource=DataSource; ReadOnly=True; Options=RowSelect zusätzlich aktivieren; Align=alClient; Columns=Add All Fields, ggf. Feldeigenschaften anpassen, wie Titel (Title), Spaltenbreite (Width) Projekt kompilieren und Unit speichern unter umain ausführen (F9) Projekt speichern unter ropdelphisqliteeinstieg Design Run Run (Spaltentitel angepasst) Abbildung 5 Abbildung 6 Abbildung 7 HINWEIS Formular entsprechend erweitern, wie z.B. TDBNavigator Komponente, TEdit für SQL-Befehl SELECT. © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 10- SQLite3 mit Delphi XE3 03.09.2013 SQLite Datenbank Datensätze im DBGrid (Aktionen) Eine vorhandene SQLite Datenbank öffnen und die Datensätze in einem DBGrid zeigen. Verwendet werden Aktionen (Actions). Form und Komponente haben den gleichen Aufbau, wie im vorherigen Beispiel. Aktivität SQLite Datenbank verbinden Beschreibung Aktion (Action) Procedure TfrmMain.ActionDBConnectExecute(Sender: TObject); Begin Try SQLConnection.Connected := False; SQLDataSet.Active := Connected; SQLConnection.Params.Values['Database'] := '<SQLite DB Pfad>'; SQLConnection.Params.Values['FailIfMissing'] := 'False'; SQLConnection.Connected := True; Except On E: EDatabaseError Do ShowMessage(E.Message); End; End; SQL-Abfrage ausführen und Datensätze im TDBGrid zeigen Procedure TfrmMain.ActionQueryToDBGridExecute(Sender: TObject); Var FSQLCommandText : String; Begin // Query aus einem TMemo verwenden FSQLCommandText := memoSQLiteDBQuery.Text; // Query prüfen ob SELECT Befehl If (LeftStr(LowerCase(FSQLCommandText),6)) <> 'select') Then Begin ShowMessage('Abbruch: SQL-Query enthält kein SELECT Befehl!'); Exit; End; // SQLite DB verbinden If SQLConnection.Connected = False Then ActionSQLiteDBConnectExecute(Sender); If SQLConnection.Connected = False Then Exit; Try // ClientDataSet and SQLDataSet deaktivieren ClientDataSet.Active := False; SQLDataSet.Active := False; // SQL-Befehl zuweisen SQLDataSet.CommandText := FSQL; // ClientDataSet and SQLDataSet aktivieren SQLDataSet.Active := True; ClientDataSet.Active := True; // Query ausführen SQLDataSet.Open; Except On E: EDatabaseError Do ShowMessage(E.Message); End; End; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 11- SQLite3 mit Delphi XE3 03.09.2013 SQLConnection Die Verbindung mit einer SQLite Datenbank (Datei) erfolgt über die Komponente dbExpress TSQLConnection. SQLConnection Vorbereiten Delphi Projekt neu erstellen oder öffnen VCL Formular neu erstellen oder wählen Komponente hinzufügen: dbExpress TSQLConnection Abbildung 8 Dataset hinzufügen um das Ergebnis eines SQL SELECT Befehls zu speichern. BEISPIELE Var FDSSQLResults: TDataSet oder eine TSQLDataSet Komponente. Abbildung 9 WICHTIG Die Datei sqlite3.dll im Projekt Verzeichnis ablegen oder im Windows System Verzeichnis. SQLConnection Eigenschaften Name: SQLConnection Connected: False (noch keine Verbindung erstellen) Driver: SQLite (nicht vergessen anzugeben) Connectioname: SQLConnect (kann beliebig sein) KeepConnection: True (Verbunden bleiben nach die Verbindung erstellt wurde) Params: FailIfMissing=False (kein Abbruch falls die Datenbank nicht gefunden wurde. Die Datenbank wird dann beim SQL-Befehl Create Table neu erstellt. Abbildung 10 HINWEIS Parameter im Code definieren mittels Parameter=Wert (OHNE Leerzeichen) SQLConnection.Params.Clear; SQLConnection.Params.Add('Database=' + 'buecher.db'); SQLConnection.Params.Add('FailIfMissing=False'); oder SQLConnection.Params.Values['Database'] := 'buecher.db'; SQLConnection.Params.Values['FailIfMissing'] := 'False'; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 12- SQLite3 mit Delphi XE3 03.09.2013 SQLConnection Verbindung öffnen Die Verbindung öffnen, nachdem der Datenbankpfad als Parameter definiert wurde. Wird nur der Dateiname angegeben, dann muss die Datei im Projektverzeichnis vorhanden sein. Try // Datenbank angeben – kann noch erweitert werden mit z.B. Pfadangabe SQLConnection.Params.Add('Database=' + 'buecher.db'); // Verbinden SQLConnection.Connected := True; Except On E: EDatabaseError Do ShowMessage(E.Message); End; HINWEISE Datenbankdatei prüfen ob vorhanden: If NOT FileExists('buecher.db') Then Abbruch; Datenbankname Pfad hinzufügen: ExtractFilePath(Application.ExeName) + 'buecher.db'; oder ExtractFilePath(ParamStr(i)) + 'buecher.db'; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 13- SQLite3 mit Delphi XE3 03.09.2013 SQL-Befehle SQL-Befehle ausführen - SQLConnection Es gibt zwei Arten von SQL-Befehlen. Mit Ergebnis: SQL-Befehl SELECT liefert Datensätze in einem TDataset. SQLConnection.Execute(SQL-Befehl, NIL, TDataset); Ohne Ergebnis: SQL-Befehle wie CREATE, INSERT, DELETE, UPDATE, DROP usw.. SQLConnection.Execute(SQL-Befehl, NIL); oder SQLConnection.ExecuteDirect(SQL-Befehl); BEISPIEL SELECT Alle Datensätze der Tabelle Buecher in einem Dataset speichern. Fehler mit Try—Except abfangen. Var FDSSQLResults: TDataset; Try // Ergebnis SQL-Befehl SELECT speichern // Datensätze der Tabelle Buecher selektieren und in einem Dataset speichern SQLConnection.Execute('SELECT * FROM Buecher', NIL, FDSSQLResults); Except On E: EDatabaseError Do ShowMessage(E.Message); End; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 14- SQLite3 mit Delphi XE3 03.09.2013 SQL-Befehle ausführen - SQLDataSet Wird ein SQLDataSet verwendet, dann werden SQL-Befehle wie folgt ausgeführt: Mit Ergebnis: SQL-Befehl SELECT liefert Datensätze in dem SQLDataset. SQLDataset.CommandText := 'SQL SELECT Befehl'; SQLDataset.Open; Ohne Ergebnis: SQL-Befehle wie CREATE, INSERT, DELETE, UPDATE, DROP usw.. SQLDataset.CommandText := 'SQL CREATE oder INSERT … Befehl'; SQLDataset.ExecSQL; BEISPIEL SELECT Alle Datensätze aus der Tabelle Buecher selektieren und in einem Stringgrid sgSQLiteDBQueryToStringGrid darstellen. Procedure TfrmMain.SQLiteQueryToStringGrid(Sender: TObject); Var i: Integer; Begin Try FSQLCommandText := 'SELECT * FROM Buecher;'; // Alle Informationen aus der Tabelle Buecher lesen FSQLDataSet.Open; // Spaltenzahl anpassen sgSQLiteDBQueryToStringGrid.ColCount := FSQLDataSet.FieldCount + 1; // Zeilenzahl anpassen sgSQLiteDBQueryToStringGrid.RowCount := FSQLDataSet.RecordCount + 1; For i := 0 To FSQLDataSet.FieldCount -1 Do // Spaltenüberschriften SgSQLiteDBQueryToStringGrid.Cells[i + 1,0] := FSQLDataSet.Fields[i].FieldName; i := 1; FSQLDataSet.First; // Daten aus Dataset im StringGrid übertragen While NOT FSQLDataSet.EOF Do Begin sgSQLiteDBQueryToStringGrid.Cells[1,i] := FSQLDataSet.Fields[0].AsString; // Zelle Spalte 1, Zeile i sgSQLiteDBQueryToStringGrid.Cells[2,i] := FSQLDataSet.Fields[1].AsString; // Zelle Spalte 2, Zeile i FSQLDataSet.Next; i := i +1; End; Except on E: EDatabaseError do ShowMessage(E.Message); End; End; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 15- SQLite3 mit Delphi XE3 03.09.2013 SQL-Befehl Beispiele Einige Beispiele anhand der Tabelle Buecher aus der Datenbank BUECHER.DB. HINWEISE In den Beispielen werden SQL-Befehle im String LSQL gespeichert. Groß-/Kleinschreibung bei SQL-Befehlen beachten. CREATE TABLE Tabelle (Spalte1 Typ, SpalteN Typ) Beispiel: Eine neue Tabelle Buecher erstellen. HINWEIS SQLite Datentypen („Storage Classes“) : NULL, INTEGER, REAL, TEXT, BLOB SQL-Befehle um die Tabellen Autoren und Buecher zu erstellen: Var LSQLCreateAutoren, LSQLCreateBuecher, LSQLCreateLog: String; LSQLCreateAutoren := 'CREATE TABLE Autoren (AutorID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, Name VARCHAR(40) NOT NULL, Beschreibung VARCHAR(255), Homepage VARCHAR(100));'; LSQLCreateBuecher := 'CREATE TABLE Buecher (BuchID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, Titel VARCHAR(100) NOT NULL, AutorID INTEGER, ISBN VARCHAR(20));'; LSQLCreateLog := 'CREATE TABLE Log (LogID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, Datum VARCHAR(20) NOT NULL, Info VARCHAR(255) NOT NULL);'; SQLConnection Execute Möglichkeit: SQLConnection.Execute(LSQLCreateAutoren,NIL); SQLConnection.Execute(LSQLCreateBuecher,NIL); SQLConnection.Execute(LSQLCreateLog,NIL); HINWEISE Tabelle erstellen, falls nicht vorhanden: CREATE TABLE IF NOT EXISTS … Anstatt SQLConnection.Execute(SQL-Befehl) kann auch SQLConnection.ExecuteDirect(SQLBefehl) eingesetzt werden Namen für Tabellen und Spalten können auch in Anführungszeichen angegeben werden. Vgl. "Buecher". Datentyp TEXT wird in DBGRID als Memo dargestellt. Um eine Zeichenkette (String) darzustellen, VARCHAR(Länge) verwenden. Vgl. VARCHAR(20) entspricht einer Zeichenkette mit der Länge von 20 Zeichen. SQLDataSet ExecSQL Möglichkeit: SQLDataset.CommandText := LSQLCreateAutoren; SQLDataset.ExecSQL; SQLDataset.CommandText := LSQLCreateBuecher; SQLDataset.ExecSQL; SQLDataset.CommandText := LSQLCreateLog; SQLDataset.ExecSQL; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 16- SQLite3 mit Delphi XE3 03.09.2013 INSERT INTO Tabelle (Spalte1, SpalteN) VALUES (Wert1, WertN) BEISPIEL: DATENSÄTZE IN DIE TABELLE BUECHER EINFÜGEN. Via SQLConnection.ExecuteDirect SQLConnection.ExecuteDirect('INSERT INTO Buecher(Titel) VALUES("Titel 1");'); SQLConnection.ExecuteDirect('INSERT INTO Buecher(Titel, AutorID) VALUES("Titel 2", 1);'); Via einem TSQLDataSet (siehe auch weiter unten) Testdaten mittels For Schleife erstellen: For i := 1 To 5 Do Begin SQLDataset1.CommandText := 'INSERT OR REPLACE INTO Buecher (BuchID, Titel, AutorID, ISBN) ' + 'VALUES(NULL, "Titel ' + IntToStr(i) + '", "' + IntToStr(i) + '", "' + IntToStr(i) + '");'; SQLDataset1.ExecSQL; End; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 17- SQLite3 mit Delphi XE3 03.09.2013 INSERT INTO Tabelle (Spalte1, SpalteN) VALUES (:Spalte1, :SpalteN) Datensätze können in die Tabelle Buecher auch durch Angabe von Parametern einfügt werden. Die Verwendung von Parametern, :Spalte1 .. :SpalteN, vereinfacht die Handhabung der Zuweisung von Werten. BEISPIEL SQLCONNECTION > SQLDATASET > STRINGGRID SQLDataSet definieren: Abbildung 11 SQLDataSet1 ist mit SQLConnection1 verbunden. Abbildung 12 Abbildung 13 Tabelle Buecher Spalten mit Testdaten füllen: For i := 1 To 5 Do Begin // Parameter definieren (Spaltennamen verwenden) CommandText := 'INSERT INTO Buecher (BuchID, Titel, AutorID, ISBN) VALUES(:BuchID, :Titel, :AutorID, :ISBN);'; // Parameter Werte zuweisen (Spaltennamen verwenden) SQLDataset1.ParamByName('BuchID').Value := NULL; SQLDataset1.ParamByName('Titel').Value := 'Mein Buch ' + IntToStr(i); SQLDataset1.ParamByName('AutorID').Value := i; SQLDataset1.ParamByName('ISBN').Value := 'ISBN' + IntToStr(i); // Und Werte in der Tabelle Buecher einfügen SQLDataset1.ExecSQL; End; Ausgabe im StringGrid: CommandText := ' SELECT * FROM Buecher;'; SQLDataset1.Open; StringGrid1.ColCount := SQLDataset1.FieldCount + 1; // Spalten StringGrid1RowCount := SQLDataset1.RecordCount + 1; // Zeilen // Spaltenüberschrift For i := 0 To FieldCount - 1 Do StringGrid1.Cells[i + 1,0] := SQLDataset1.Fields[i].FieldName; // Werte im Stringgrid ausgeben i := 1; SQLDataset1.First; While NOT SQLDataset1.EOF Do Begin // Spalte Nr SQLDataset1.Cells[1,i] := SQLDataset1.Fields[0].AsString; // Spalte Titel SQLDataset1.Cells[2,i] := SQLDataset1.Fields[1].AsString; SQLDataset1.Next; i := i + 1; End; Abbildung 14 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 18- SQLite3 mit Delphi XE3 03.09.2013 SELECT Spalten FROM Tabelle(n) WHERE Bedingung ORDER BY Sortierung GROUP BY Gruppierung HAVING Einschränkung Bestimmte Datensätze lesen und als Ergebnis in einem Dataset zurückgeben. SELECT Operator * DISTINCT COUNT(*) GROUP BY GROUP BY ... HAVING ORDER BY … ASC, DESC Aggregatfunktionen WHERE Operator = <> > < >= <= BETWEEN LIKE IN IS NULL IS NOT NULL AND, OR Bedeutung Alle Felder eine Tabelle anzeigen Felder kumuliert anzeigen Anzahl Treffer zur optionalen Bedingung Ergebnis gruppieren Ergebnis gruppiert einschränken Ergebnis auf- oder absteigend sortieren MIN(Feld), MAX(Feld), AVG(Feld), SUM(Feld), COUNT(Feld) Bedeutung Gleich Ungleich Größer Kleiner Größer Gleich Kleiner gleich Zwischen einem numerischen Bereich Ungefähre Übereinstimmung Platzhalter % (beliebig viele Zeichen), _ (ein Zeichen) einem Wertesatz Leere Einträge abfragen Keine leeren Einträge abfragen Verknüpfung logischer Operationen BEISPIELE Anhand TSQLDataset Alle Datensätze der Tabelle Buecher lesen Nur Buch mit ISBN 1 selektieren Alle Datensätze sortiert nach Titel absteigend DESC; oder aufsteigend ASC Alle Datensätze mit AutorID und Autorname (SELECT auf mehrere Tabellen (JOIN)) SQL-Befehl ausführen. Das Ergebnis wird im SQLDataset gespeichert. SQLDataset.CommandText := 'SELECT * FROM Buecher'; 'SELECT * FROM Buecher WHERE ISBN = "ISBN 1" '; 'SELECT * FROM Buecher ORDER BY Titel DESC'; 'SELECT Buecher.BuchID,Buecher.Titel,Buecher.AutorID, Autoren.Name,Buecher.ISBN FROM Autoren, Buecher WHERE Autoren.AutorID=Buecher.AutorID'; SQLDataset.Open; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 19- SQLite3 mit Delphi XE3 03.09.2013 UPDATE Tabelle SET Spalte1=Wert, SpalteN=Wert WHERE Spalte=Bedingung Beispiel: Tabelle Buecher aktualisieren. Aufgabe: Titel 2 in Buchtitel 2 ändern SQLConnection.ExecuteDirect('UPDATE Buecher SET Titel="Buchtitel 2", isbn="ISBN 2-2" WHERE Titel="Titel 2";'); DELETE FROM TABLE WHERE Spalte=Bedingung Beispiel: Alle Datensätze aus der Tabelle Buecher löschen. SQLConnection.ExecuteDirect('DELETE FROM Buecher;'); Beispiel: Datensatz mit der BuchID=1 aus der Tabelle Buecher löschen. SQLConnection.ExecuteDirect('DELETE FROM Buecher WHERE BuchID=1;'); DROP TABLE Tabellenname Beispiel: Tabelle Buecher aus der Datenbank löschen. SQLConnection.ExecuteDirect('DROP TABLE IF EXISTS Buecher;'); CREATE INDEX Indexname ON Tabelle(Spalte) Beispiel: Auf Spalte ISBN einen eindeutigen Index erstellen. SQLConnection.ExecuteDirect('CREATE UNIQUE INDEX idx_isbn ON Buecher(ISBN);'); HINWEIS SQLite verwendet den Index automatisch. DROP INDEX Indexname Beispiel: Index idx_isbn löschen. SQLConnection.ExecuteDirect('DROP INDEX IF EXISTS idx_isbn;'); © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 20- SQLite3 mit Delphi XE3 03.09.2013 VIEWS Views sind Tabellen, die ein bestimmtes Ergebnis zeigen. Auf Views können SQL SELECT Befehle ausgeführt werden. CREATE VIEW Name AS SELECT Befehl Verschiedene Beispiele (verwendet Var LSQL: String für den SQL-Befehl). View erstellen auf alle Buecher: LSQL := 'CREATE VIEW AlleBuecher AS SELECT * FROM Buecher;'; SQLConnection.Execute(LSQL, NIL); Alle Buecher zeigen: LSQL := 'SELECT * FROM AlleBuecher;'; SQLConnection.Execute(LSQL, NIL, FDLSQLResults); View erstellen auf alle Buecher die eine „1“ im Titel haben: LSQL := 'CREATE VIEW Titel1Buecher AS SELECT * FROM Buecher WHERE Titel LIKE "%1"'; SQLConnection.Execute(LSQL, NIL); // Alle Datensätze View Titel1Buecher zeigen LSQL := 'SELECT * FROM Titel1Buecher'; SQLConnection.Execute(LSQL, NIL, FDLSQLResults); DROP VIEW Viewname View löschen: LSQL := 'DROP VIEW IF EXISTS AlleBuecher '; SQLConnection.Execute(LSQL, NIL); © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 21- SQLite3 mit Delphi XE3 03.09.2013 TRIGGER Ein Trigger ist ein Ereignis, das ausgeführt wird, wenn in der Datenbank eine bestimmte Aktion (wie zum Beispiel SQL-Befehl Insert, Update, Delete) durchgeführt wird. CREATE TRIGGER Name AFTER Aktion ON Tabelle BEGIN Ereignis; END BEISPIEL AUFGABE Alle Änderungen der Tabelle Buecher mit den SQL-Befehlen INSERT, UPDATE oder DELETE,in eine Tabelle Log schreiben. Das Änderungsdatum und das Buch, das geändert wurde, sollen gespeichert („gelogged“) werden. Tabelle Log erstellen SQL-Befehle als Konstanten definieren: Const CSQLDROPTABLELOG = 'DROP TABLE IF EXISTS Log;'; CSQLCREATETABLELOG = 'CREATE TABLE Log (' + 'LogID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL VARCHAR(255));'; UNIQUE, Datum VARCHAR(20), Info In eine Prozedur, z.B. FormCreate die Tabelle Log neu erstellen: SQLConnection.ExecuteDirect(CSQLDROPTABLELOG); SQLConnection.ExecuteDirect(CSQLCREATETABLELOG); © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 22- SQLite3 mit Delphi XE3 03.09.2013 Trigger erstellen SQL-Befehle als Konstanten definieren: Const CR = #13#10; CSQLDROPTRIGGERBI = 'DROP TRIGGER IF EXISTS Buecher_I;'; CSQLCREATETRIGGERBI = 'CREATE TRIGGER Buecher_I AFTER INSERT ON Buecher ' + CR + 'BEGIN' + CR + ' INSERT INTO Log(Datum, Info) ' + CR + ' VALUES (DATETIME(''now''), ''Neu: '' || new.Titel);' + CR + 'END;'; CSQLDROPTRIGGERBU = 'DROP TRIGGER IF EXISTS Buecher_U;'; CSQLCREATETRIGGERBU = 'CREATE TRIGGER Buecher_U AFTER UPDATE ON Buecher ' + CR + 'BEGIN' + CR + ' INSERT INTO Log(Datum, Info) ' + CR + ' VALUES (DATETIME(''now''), ''Geändert: '' || old.Titel || '' auf '' || new.Titel);'+ CR + 'END;'; CSQLDROPTRIGGERBD = 'DROP TRIGGER IF EXISTS Buecher_D;'; CSQLCREATETRIGGERBD = 'CREATE TRIGGER Buecher_D AFTER DELETE ON Buecher ' + CR + 'BEGIN' + CR + ' INSERT INTO Log(Datum, Info) ' + CR + ' VALUES (DATETIME(''now''), ''Gelöscht: '' || old.Titel);' + CR + 'END;'; In eine Prozedur, z.B. FormCreate die Trigger neu erstellen: SQLConnection.ExecuteDirect(CSQLDROPTRIGGERBI); SQLConnection.ExecuteDirect(CSQLCREATETRIGGERBI); usw. für TRIGGERBU und TRIGGERBD. Änderungen der Tabelle „Log“ anzeigen SELECT * FROM Log; Es wurde Titel hinzugefügt. Abbildung 15 Alle Einträge der Tabelle „Log“ löschen DELETE FROM Log; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 23- SQLite3 mit Delphi XE3 03.09.2013 PRAGMA PRAGMA sind spezielle SQLite Befehle, um interne Informationen aus der Datenbank zu ermitteln. PRAGMA Befehle werden wie SQL-Befehle ausgeführt. Das Ergebnis wird wiederum im Dataset gespeichert (siehe unter „SQL SELECT ausführen“). Beispiel PRAGMA Befehl ausführen und Ergebnis im TMemo zeigen: … SQLConnection.Execute(LSQL, NIL, FDLSQLResults); FDLSQLResults.First; While Not FDLSQLResults.EOF Do Begin currentLine := ''; For i := 0 to FDLSQLResults.FieldCount - 1 do currentLine := currentLine + ' ' + FDLSQLResults.Fields[i].AsString; // Datensatz hinzufügen memoSQLOutput.Lines.Add(currentLine); FDLSQLResults.Next; End; … PRAGMA database_list Liste der Datenbanken: LSQL := 'PRAGMA database_list;'; SQLConnection.Execute(LSQL, NIL, FDLSQLResults); ERGEBNIS 0 main E:\Daten\ropbooks\ropdelphisqlite\bookprojects\ropdelphisqlite\buecher.db PRAGMA table_info (Tabellenname) Tabellenstruktur ermitteln: LSQL := 'PRAGMA table_info(Buecher);'; SQLConnection.Execute(LSQL, NIL, FDLSQLResults); ERGEBNIS Ausgebene wird folgende Feldinformation: CID = SPALTENNUMMER NAME = SPALTENNAME TYPE = SPALTENTYP NOTNULL = OB KEIN WERT ERLAUBT IST DFLT_VALUE = VORGABEWERT PK = OB SPALTE TEIL DES “PRIMARY KEY“ IST (cid, name, type, notnull, dflt_value, pk) (Spaltennr, Spaltenname, Data Type, NOT NULL, Vorgabewert, Primary Key) 0 id INTEGER 1 1 titel TEXT 1 2 autor TEXT 0 3 isbn TEXT 0 1 0 0 0 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 24- SQLite3 mit Delphi XE3 03.09.2013 PRAGMA index_list (Tabellenname) Liste der Indices: LSQL := 'PRAGMA index_list(Buecher);'; SQLConnection.Execute(LSQL, NIL, FDLSQLResults); ERGEBNIS 0 idx_isbn 1 1 sqlite_autoindex_Books_1 1 PRAGMA index_info (Indexname) Indexstruktur ermitteln: LSQL := 'PRAGMA index_info(idx_isbn);'; SQLConnection.Execute(LSQL, NIL, FDLSQLResults); ERGEBNIS 0 3 isbn PRAGMA auto_vacuum Datenbank defragmentieren: LSQL := 'PRAGMA auto_vacuum;'; SQLConnection.Execute(LSQL, NIL, FDLSQLResults); ERGEBNIS Es wird kein Ergebnis zurück geliefert. PRAGMA integrity_check Datenbank Integrität prüfen: LSQL := 'PRAGMA integrity_check;'; SQLConnection.Execute(LSQL, NIL, FDLSQLResults); ERGEBNIS OK oder Hinweis. © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 25- SQLite3 mit Delphi XE3 03.09.2013 SQLite SELECT Beispiele SELECT ausführen Wie schon erwähnt, liefert der SQL-Befehl SELECT ein Ergebnis in einem TDataset. Beispiel SQL-Befehl SELECT und Ergebnis in einem TMemo „memoSQLOutput“ ausgeben: Var fSLNames: TStringList; i: Integer; currentField: TField; currentLine: string; Begin // Liste Feldnamen Tabelle // Laufvariable // Das aktuelle Tabellenfeld // Aktuelle Memozeile Feldergebnis memoSQLOutput.Lines.Add('Datensätze:' +IntToStr(FDLSQLResults.RecordCount)); fSLNames := TStringList.Create; // Liste der Feldnamen initialisieren FDLSQLResults.GetFieldNames(fSLNames); // Feldnamen lesen Ergebnisdataset FDLSQLResults.First; // Ergebnis Satz für Satz lesen While NOT FDLSQLResults.Eof Do Begin currentLine := ''; For i := 0 To fSLNames.Count - 1 Do Begin currentField := FDLSQLResults.FieldByName(fSLNames[i]); currentLine := currentLine + ' ' + currentField.AsString; End; memoSQLOutput.Lines.Add(currentLine); // Datensatz anzeigen FDLSQLResults.Next; End; fSLNames.Free; End; WICHTIG Es gibt Situationen, in denen nicht alle Informationen des SELECT Befehls im TDataSet gespeichert werden. Obwohl TDataSet Daten enthält, kann es zu Fehlermeldungen kommen, wie „Reader has no more rows“. Ein Beispiel ist die Anwendung von TDataSet.RecordCount. Um die Anzahl der Datensätze zu ermitteln, ist es sicherer, eine eigene Funktion zu definieren, anstatt RecordCount zu verwenden. Function TfrmMain.DatasetRecordCount(DS: TDataSet): Integer; Var i : Integer; Begin Result := 0; If DS = NIL Then Exit; If DS.IsEmpty Then Exit; i := 0; DS.First; While Not DS.Eof Do Begin i := i + 1; DS.Next; End; Result := i; End; Aufruf: nCnt := DatasetRecordCount(FDSSQLResults); © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 26- SQLite3 mit Delphi XE3 03.09.2013 SELECT Ergebnis im StringGrid darstellen Beispiel Ergebnis SQL-Befehl SELECT in einem StringGrid ausgeben. StringGrid Komponente Form hinzufügen: sgSQLResults: TStringGrid; Prozedur erstellen der das SQL-Ergebnis in einem StringGrid zeigt Procedure TfrmMain.ActionSQLResultsToStringGridExecute(Sender: TObject); Var nCol, nLin: Integer; Begin If Not FDLSQLResults.IsEmpty Then Begin sgSQLResults.ColCount := FDLSQLResults.FieldCount + 1; sgSQLResults.RowCount := FDLSQLResults.RecordCount + 1; sgSQLResults.FixedCols := 1; sgSQLResults.FixedRows := 1; // Spaltenüberschriften setzen For nCol := 0 To FDLSQLResults.FieldCount - 1 Do sgSQLResults.Cells[nCol + 1, 0] := FDLSQLResults.Fields[nCol].FieldName; nLin := 0; // Daten im Stringgrid zeigen FDLSQLResults.First; While Not FDLSQLResults.Eof Do Begin For nCol := 0 To FDLSQLResults.FieldCount - 1 Do Begin sgSQLResults.Cells[nCol + 1, nLin + sgSQLResults.FixedRows] := FDLSQLResults.Fields[nCol].AsString; End; FDLSQLResults.Next; Inc(nLin); End; End; End; SQL-Befehl SELECT ausführen und Ergebnis im StringGrid zeigen Try SQLConnection.Execute('SELECT * FROM Buecher', NIL, FDLSQLResults); ActionSQLResultsToStringGridExecute(Sender); Except On E: EDatabaseError Do ShowMessage(E.Message); End; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 27- SQLite3 mit Delphi XE3 03.09.2013 SELECT Ergebnis TLabel und TEdit zuweisen Das Ergebnis des SQL SELECT Befehls wird in einem TDataSet gespeichert. Die Werte aus dem TDataSet können entsprechenden Komponenten wie TLabel, TEdit, TLabeledEdit usw. zugewiesen werden. Var ledTitel: TLabeledEdit; lblTitel: TLabel; // Tabelle Buecher, Spalte Titel Wert an TLabeledEdit und TLabel zuweisen ledTitel.Text := FDLSQLResults.FieldByName('Titel').AsString; lblTitel.Caption := FDLSQLResults.FieldByName('Titel').AsString; SELECT Ergebnis TStringList und TListBox zuweisen Das Ergebnis des SQL SELECT Befehls in einem TStringList speichern und anschließend einer TListBox zuweisen. Stringlist erstellen: Function BookTitelList(LSQL: String) : TStringList; // Stringlist mit Buchtitel erstellen. // SQL-Befehl „SELECT Titel FROM Buecher;“. Var i: Integer; fSL: TStringList; DS: TDataSet; Begin fSL := TStringList.Create; Try SQLConnection.Execute(LSQL, NIL, DS); DS.First; While Not DS.Eof Do Begin fSL.Add(DS.FieldByName('Titel').AsString); DS.Next; End; Except On E: Exception Do ShowMessage(E.Message); End; Result := fSL; end; StringList TListBox zuweisen: // TListbox Komponente hinzufügen Var lbCodeList: TListBox; // Alle Buchtitel in der Listbox zeigen. lbCodeList.Items := BookTitelList('SELECT Titel FROM Buecher;'); HINWEIS SELECT Befehl erweitern, z.B. mit WHERE ISBN = '123'; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 28- SQLite3 mit Delphi XE3 03.09.2013 SELECT Ergebnis in HTML Tabelle ausgeben Inhalt SQL-Tabelle in eine HTML Tabelle ausgeben und im Standardbrowser darstellen. Procedure TfrmMain.ActionSQLSelectAllBooksToHTMLExecute(Sender: TObject); Const CCRLF = #13#10; CHTMLCSS = '<style type='''+ 'text/css' + '''>' + CCRLF + 'table { width:100%; background-color:#D7E4F2; border:1px; } '+ CCRLF + 'h1 { font:bold 2.0em Arial; color:#000080; background-color:#; border:1px; solid #000; vertical-align:top; overflow:hidden; }' + CCRLF + 'th { font:bold 1.6em Arial; color:#000080; background-color:#F0F8FF; border:1px; solid #000; vertical-align:top; overflow:hidden; }' + CCRLF + 'td { font:normal 1.0em Arial; color:#000000; background-color:#; border:1px; solid #000; vertical-align:top; overflow:hidden; }' + CCRLF + 'div { font:normal 0.6em Arial; color:#000080; background-color:#; border:1px; solid #000; vertical-align:top; overflow:hidden; }' + CCRLF + '</style>'; CHTMLBEGIN = '<HTML>' + CCRLF + '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">' + CCRLF + '<HEAD>' + CCRLF+ CHTMLCSS + CCRLF + '</HEAD><BODY bgcolor=#FFFFFF><H1>Buchtitel</H1><TABLE>'; CHTMLEND = '</TABLE><p><div>Erstellt mittels ropDelphiSQLite (c) 2013 Robert W.B. Linn, Pinnberg, Germany</div></p></BODY></HTML>'; Var DS: TDataSet; fSL: TStringList; sFile, sField: String; i: Integer; Begin Try SQLConnection.Execute('SELECT * FROM Buecher', NIL, DS); Except On E: Exception Do Begin ShowMessage(E.Message); Exit; End; End; If DS.IsEmpty Then Exit; sFile := ExtractFilePath(Application.ExeName) + 'booklist.htm'; fSL := TStringList.Create; fSL.Add(CHTMLBEGIN); fSL.Add('<TR>'); For i := 0 To FieldCount - 1 Do fSL.Add('<TH>' + DS.Fields[i].FieldName + '</TH>'); fSL.Add('</TR>'); DS.First; While Not DS.Eof Do Begin fSL.Add('<TR>'); For i := 0 To DS.FieldCount - 1 Do Begin sField := DS.Fields[i].AsString; If sField = '' Then sField := '&nbsp;'; fSL.Add('<TD>' + sField + '</TD>'); End; DS.Next; fSL.Add('</TR>'); End; fSL.Add(CHTMLEND); fSL.SaveToFile(sFile); ShellExecute(Handle, NIL, PChar(sFile), NIL, NIL, SW_SHOW); End; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 29- SQLite3 mit Delphi XE3 03.09.2013 SELECT auf mehrere Tabellen (JOIN) BEISPIEL Alle Autor Name (Tabelle Autoren) und Titel (Tabelle Buecher) sortiert nach Autor Name ausgeben. SQL-Befehl SELECT und Ergebnis: Abbildung 16 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 30- SQLite3 mit Delphi XE3 03.09.2013 SELECT sqlite_master Die spezielle SQLite Tabelle sqlite_master enthält alle Informationen über Tabellen, Indizes, Views, Trigger einer SQLite Datenbank. Der SELECT Befehl verwenden um Informationen aus der Tabelle sqlite_master zu lesen. Das Ergebnis sind die Spalten type (table, index, view, trigger), name, tbl_name, rootpage und sql. BEISPIELE ANHAND DER DATENBANK BUECHER.DB ALLE DATENSÄTZE DER TABELLE SQLITE_MASTER SELECT * FROM sqlite_master; Abbildung 17 ALLE TABELLENNAMEN DER TABELLE SQLITE_MASTER SELECT NAME FROM SQLITE_MASTER WHERE TYPE="TABLE" ORDER BY NAME; name Autoren Buecher Log sqlite_sequence SELECT CAST ( Ausdruck AS Datentyp [ ( Länge ) ] ) CAST in SQLite konvertiert einen Ausdruck von einem Datentyp in einen anderen. BEISPIELE Die Tabelle sqlite_master enthält alle SQLite Datenbankinformationen, wie Tabellen, Indices, Views, Triggers. Ausgabe Liste der Tabellentypen und Tabellenname: Ohne Cast SELECT type, tbl_name FROM sqlite_master Abbildung 18 Mit Cast SELECT type AS "Typ", (CAST(tbl_name AS VARCHAR(10))) AS "Tabellen" FROM sqlite_master Abbildung 19 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 31- SQLite3 mit Delphi XE3 03.09.2013 SQLite und FireDAC Einstieg Eine einfache Anwendung, Liste der Bücher aus der Beispieldatenbank Buecher.db, zeigt die Verwendung der FireDAC Komponenten. HINWEIS Eine detaillierte Beschreibung wie SQLite unter FireDAC verwendet wird, ist in der FireDAC zu finden unter „Using SQLite with FireDAC“ (siehe Delphi DIE Menü FireDAC > Help). Aktivität Delphi Projekt erstellen oder öffnen, Form wählen Komponenten hinzufügen TADConnection Beschreibung Vgl. frmMain HINWEIS Sicherstellen das unter Project > Options > Delphi Compiler > Unit output directory ein Verzeichnis angegeben ist. Vgl. .\$(Platform)\$(Config) oder .\ Params.Strings = ( 'DriverID=SQLite' 'Database=buecher.db' 'OpenMode=ReadWrite' 'SharedCache=false' 'LockingMode=Normal') FetchOptions.AssignedValues = [evMode] UpdateOptions.AssignedValues = [uvUpdateMode] UpdateOptions.UpdateMode = upWhereAll Connected = True LoginPrompt = False TADQuery Active = True Connection = ADConnection1 SQL.Strings = ('SELECT * FROM Buecher') ADPhysSQLiteDriverLink ADGUIxWaitCursor TDatasource Keine Anpassungen notwendig. DataSet = ADQuery1 TDBGrid DataSource = DataSource1 TDBNavigator DataSource = DataSource1 Entwurf Abbildung 20 Anwendungen ausführen Abbildung 21 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 32- SQLite3 mit Delphi XE3 03.09.2013 SQLite spezielle Anwendungsbeispiele SQLite Datensätze im DBGRID Download Delphi XE3 Quellcode ropDelphiSQLiteDBGrid Um eine SQLite Datenbank mit einem DBGrid zu verbinden, werden verschiedene Komponenten benötigt: TSQLConnection (dbExpress) -> TSQLDataSet (dbExpress) -> TDataSetProvider (Data Access)> ClientDataSet (Data Access)-> TDataSource (Data Access) -> TDBGrid (Data Controls) Siehe grafische Darstellung (startet mit SQLConnection1 … DataSource1) Abbildung 22 HINWEISE DBGrid1 ist mit DataSource1 verbunden. DBNavigator1 ist auch mit DataSource1 verbunden. Änderungen können im DBGrid1 direkt oder mittels DBNavigator1 vorgenommen werden. Wenn die Anwendungen verlassen werden, müssen die Daten aus dem DBGrid1 in die SQLite Datenbank gespeichert werden. Hierzu wird ClientDataSet1.ApplyUpdates verwendet. © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 33- SQLite3 mit Delphi XE3 03.09.2013 AUSSCHNITTE AUS EINER BEISPIELANWENDUNG Verwendet wird die SQLite Datenbank BUECHER.DB mit den Tabellen Buecher und Autoren. Verbindung mit der SQLite Datenbank herstellen: Procedure TfrmMain.ActionDatabaseConnectExecute(Sender: TObject); Begin Try SQLDataset1.Close; SQLConnection1.Close; SQLConnection1.Params.Values['Database'] := 'buecher.db'; //ggf. Pfadangabe SQLConnection1.Params.Values['FailIfMissing'] := 'False'; SQLConnection1.Open; Except On E: EDatabaseError Do ShowMessage(E.Message); End; End; Daten selektieren und im DBGrid darstellen: Procedure TfrmMain.ActionTableGetDataExecute(Sender: TObject); // Daten aus der SQLite Tabelle Buecher und Autoren lesen und im DBGrid anzeigen // Verwendet wird ein SQL Select JOIN Befehl. Begin Try ClientDataSet1.Active := False; SQLDataset1.CommandText := 'SELECT Buecher.BuchID,Buecher.Titel,Buecher.AutorID, Autoren.Name,Buecher.ISBN FROM Autoren, Buecher WHERE Autoren.AutorID=Buecher.AutorID;'; SQLDataset1.Open; // Clientdataset aktivieren um die Daten im DBGrid anzuzeigen ClientDataSet1.Active := True; Except On E: EDatabaseError Do ShowMessage(E.Message); End; End; ERGEBNIS Abbildung 23 HINWEISE Bevor der SQLDataset1.CommandText ausgeführt wird, muss zuerst das SQLDataSet deaktiviert werden. Im DBGrid wird das Ergebnis des SQL-Befehls SELECT gezeigt. Es können auch selektive Ergebnisse als SQLDataset1.CommandText gezeigt werden. Vgl. 'SELECT * FROM Buecher WHERE BuchID < 3;' oder 'SELECT * FROM Buecher ORDER BY ISBN DESC'; oder JOIN 'SELECT Autoren.Name,Buecher.Titel FROM Autoren, Buecher WHERE Autoren.AutorID=Buecher.AutorID;' © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 34- SQLite3 mit Delphi XE3 03.09.2013 Daten in einen DBGrid mittels DBNavigator einfügen – spezieller Fall AutoInc Feld Wird ein AutoInc Feld benutzt, dann muss dieses Feld mit einem Wert belegt werden, bevor der Datensatz im CleintDataSet gespeichert wird. Unter Verwendung eines DBNavigators, macht SQLite das nicht automatisch. BEISPIEL TABELLE BUECHER, FELD BUCHID (AUTOINC). Definiert wird eine Prozedur ClientDataSetBeforPost, die eine Funktion GetNextBuchID verwendet. Procedure TfrmMain.ClientDataSet1BeforePost(DataSet: TDataSet); Begin // Feld BuchID auf NULL prüfen und den nächst höheren Wert zuweisen. If TClientDataSet(DataSet).FieldByName('BuchID').IsNull Then TClientDataSet(DataSet).FieldByName('BuchID').Value := GetNextBuchID; End; Function TfrmMain.GetNextBuchID: Integer; // Nächst höheren Wert für Feld BuchID definieren Begin SQLDataset1.Close; SQLDataset1.CommandText := 'SELECT Max(BuchID) FROM Buecher;'; SQLDataset1.Open; Result := SQLDataset1.Fields[0].AsInteger + 1; SQLDataset1.Close; End; Daten aus dem ClientDataSet in der SQLite Datenbank speichern Im DBGrid können Daten bearbeitet werden. Da diese im Speicher verbleiben, müssen Änderungen vom ClientDataSet auch in der SQLite Datenbank gespeichert werden. Verwende hierzu ClientDataSet.ApplyUpdates. Procedure TfrmMain.ClientDataSet1BeforeRefresh(DataSet: TDataSet); Begin If DataSet = NIL Then Abort; If TClientDataSet(DataSet).Active = False Then Abort; If TClientDataSet(DataSet).ChangeCount > 0 Then begin TClientDataSet(DataSet).ApplyUpdates(-1); end; End; HINWEIS Um sicherzustellen, dass Änderungen auch beim Verlassen der Anwendung in der SQLite Datenbank gespeichert werden, ClienDataSet1BeforeRefresh() in FormClose aufrufen. Procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction); Begin ClientDataSet1BeforeRefresh(ClientDataSet1); End; © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 35- SQLite3 mit Delphi XE3 03.09.2013 SQLite BLOBs verwenden Download Delphi XE3 Quellcode ropDelphiSQLiteBlob. Tabelle mit BLOB Spalte definieren: Try SQLConnection.ExecuteDirect('CREATE TABLE images (' + 'id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,' + 'title TEXT NOT NULL, ' + 'image BLOB NOT NULL)'); Except On E: EDatabaseError Do ShowMessage(E.Message); End; BLOB in Tabelle images Feld image laden: Procedure TfrmMain.InsertPicture(Sender: TObject; sTitle, sImagePath: String); // Titel und Image in der SQL-Tabelle images laden Var streamImage: TMemoryStream; // Stream um Datei Image zu speichern LTransaction: TDBXTransaction; LDBXCmd: TSQLQuery; // SQLConnection Transaktion // SQL-Query LParam: TParam; LSQL: String; // Parameter für SQL-Query // SQL-Befehl begin // SQL-Befehl INSERT zusammenstellen - achte auf "value ?" für image LSQL := 'INSERT INTO images(title, image) VALUES("' + sTitle + '", ?)'; // Stream erstellen - LoadFromFile kann noch erweitert werden mit z.B. // If FileExists... streamImage := TMemoryStream.Create; streamImage.LoadFromFile(sImagePath); // Transaktion eröffnen LTransaction := SQLConnection.BeginTransaction; // Query Befehl zusammenstellen LDBXCmd := TSQLQuery.Create(SQLConnection); Try Try LDBXCmd.SQLConnection := SQLConnection; LDBXCmd.SQL.Text := LSQL; LParam := LDBXCmd.Params.CreateParam(ftBlob, 'Picture', ptInput); LParam.LoadFromStream(streamImage, ftBlob); LDBXCmd.ExecSQL; Except On E: Exception Do SQLConnection.RollbackFreeAndNil(LTransaction); End; SQLConnection.CommitFreeAndNil(LTransaction); Finally LDBXCmd.Free; End; End; Aufrufbeispiel Bitmap m.bmp aus dem Anwendungs-/Projektverzeichnis in der Tabelle laden InsertPicture(Sender, 'M', ExtractFilePath(Application.ExeName) + 'm.bmp'); © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 36- SQLite3 mit Delphi XE3 03.09.2013 Inhalt BLOB in Formular TImage zeigen: Procedure TfrmMain.LoadPicture(Sender: TObject; sTitle: String); // Titel und Bild in Label und Image laden Var LSQL: String; // SQL-Befehl DS: TDataSet; BlobField: TField; // Resultat SQL-Befehl Select // Blobfeld benötigt für BlobStream BS: TStream; BM: TBitMap; // BS Blobstream // Bitmap im Image laden Begin // Select Befehl nach Titel LSQL := 'SELECT * FROM images WHERE title = "' + sTitle + '"'; Try // SQL-Befehl ausführen und Ergebnis in DS speichern DS := NIL; SQLConnection.Execute(LSQL, NIL, DS); // Ergebnis lesen und Inhalt Label, BlobField, Bitmap und Image zuweisen If DS <> NIL Then Begin lblTitle.Caption := DS.FieldByName('title').AsString; Blobfield := DS.FieldbyName('image'); BS := DS.CreateBlobStream(BlobField, bmReadWrite); BM := TBitMap.Create; BM.LoadFromStream(BS); Image1.Picture.Bitmap := BM; End; Except On E: Exception Do ShowMessage(E.Message); End; End; Abbildung 24 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 37- SQLite3 mit Delphi XE3 03.09.2013 SQLite SQL-Befehle direkt ausführen Download Delphi XE3 Quellcode ropSQLiteIt Abbildung 25 Beispiel wie ropSQLiteIt verwendet werden kann: Eine Datenbank Logs.db mit Logging Tabelle Logs erstellen und verwenden. 1. Datei > Datenbank öffnen (Strg-O) > Dateiname logs.db 3. Tabelle Logs erstellen: CREATE TABLE logs (id INTEGER PRIMARY KEY AUTOINCREMENT, logtype TEXT, logname TEXT, logmessage TEXT, logtime DATETIME); 4. Testdaten hinzufügen: INSERT INTO logs (id,logtype,logname,logmessage,logtime) VALUES (NULL, 'TestLog1', 'TestEvent 1', 'Testaktivität 1', datetime('now')); INSERT INTO logs (id,logtype,logname,logmessage,logtime) VALUES (NULL, 'TestLog2', 'TestEvent 2', 'Testaktivität 2', datetime('now')); INSERT INTO logs (id,logtype,logname,logmessage,logtime) VALUES (NULL, 'TestLog1', 'TestEvent 3', 'Testaktivität 3', datetime('now')); 5. Testdaten zeigen: SELECT * FROM logs; SELECT * FROM logs WHERE strftime('%s', 'now')-strftime('%s', logtime) < 3600; SELECT * FROM logs WHERE logtype = "TestLog1"; SELECT logtype, COUNT(logtype) FROM logs GROUP BY logtype; 6. Testdaten löschen: DELETE FROM logs; ERGEBNIS Abbildung 26 © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 38- SQLite3 mit Delphi XE3 03.09.2013 SQLite Tabelle für Einstellungen verwenden Eine SQLite Tabelle kann auch verwendet werden, um Einstellungen einer Anwendung zu speichern oder zu lesen. Der Tabellenaufbau ist identisch mit der einer Ini-Datei: [SEKTION] Schlüssel=Wert. SQL-Tabelle System definieren und erstellen: CREATE TABLE System ( ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, syssection TEXT, syskey TEXT, sysvalue TEXT); Funktionen definieren um Werte zu speichern / lesen: Function SQLSystemRead(sSection, sKey, sDefault : String): String; Var LSQL: String; DS: TDataSet; Begin Result := sDefault; Try LSQL := 'SELECT sysvalue FROM System WHERE ' + 'syssection=' + '''' + sSection + '''' + ' AND ' + 'syskey=' + '''' + sKey + '''' + ''; SQLConnection.Execute(LSQL, NIL, DS); Result := DS.FieldByName('sysvalue').AsString; If Result = '' Then Result := sDefault; Except On E: EDatabaseError Do ShowMessage(E.Message); End; End; Function SQLSystemUpdate(sSection, sKey, sValue: String): Boolean; Var LSQL: String; DS: TDataSet; Begin Result := False; Try LSQL := 'SELECT sysvalue FROM System WHERE ' + 'syssection=' + '''' + sSection + '''' + ' AND ' + 'syskey=' + '''' + sKey + '''' + ''; SQLConnection.Execute(LSQL, NIL, DS); If DS.FieldByName('sysvalue').AsString = '' Then Begin LSQL := 'INSERT INTO system (syssection, syskey, sysvalue) VALUES (' + '''' + sSection + '''' + ', ' + '''' + sKey + '''' + ', ' + '''' + sValue + '''' + ')'; SQLConnection.Execute(LSQL, NIL); Result := True; End Else Begin LSQL := 'UPDATE system ' + 'SET ' + 'syssection=' + '''' + sSection + '''' + ', ' + 'syskey=' + '''' + sKey + '''' + ', ' + 'sysvalue=' + '''' + sValue + '''' + ' WHERE ' + 'syssection=' + '''' + sSection + '''' + ' AND ' + 'syskey=' + '''' + sKey + '''' + ''; SQLConnection.Execute(LSQL, NIL); © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 39- SQLite3 mit Delphi XE3 03.09.2013 End; Except On E: EDatabaseError Do ShowMessage(E.Message); End; End; Anwenden z.B. in FormCreate, FormClose Procedure TfrmMain.FormCreate = Form Top Position lesen und setzen Top := StrToInt(SQLSystemRead('MAINPOSITION', 'Top', '100')); Procedure TfrmMain.FormClose = Form Top Position speichern SQLSystemUpdate('MAINPOSITION', 'Top', IntToStr(Top)); © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 40- SQLite3 mit Delphi XE3 03.09.2013 Anhang Fehlermeldungen und Abhilfe (unvollständige Liste!) Eine unvollständige Liste von SQLite Fehlermeldungen (Englisch/Deutsch) mit Ursache und Abhilfe. HINWEIS In der SQLite Quellcode Datei sqlite3.c sind Fehlercodes und Hinweise kurz beschrieben. Vgl. #define SQLITE_OK 0 /* beginning-of-error-codes */ /* Successful result */ #define SQLITE_ERROR /* SQL error or missing database */ 1 ... Meldung Sqlite3.dll not found Ursache Die notwendige DLL Datei sqlite3.dll konnte nicht im Pfad gefunden werden. No such table: TABELLE Ausführung SQL-Befehl: Die Tabelle TABELLE ist in der Datenbank nicht vorhanden. Operation not allowed on a unidirectional dataset Meldung erscheint zum Beispiel wenn versucht wird ein SQLDataset mit einem DBGrid zu verbinden. Ein SQLDataset ist ein „unidirectionales“ Dataset, welches Datensätze nur in eine Richtung transportieren kann. Ein DBGrid kann Datensätze in beide Richtungen transportieren. Daher kann ein SQLDataset nicht direkt mit einem DBGrid verbunden werden. Datenbank wurde nicht gefunden. Unable to open database file Abhilfe Sqlite3.dll entweder im Projekt / Anwendungs-Verzeichnis oder Windows System32 Verzeichnis kopieren. Wenn sqlite3.dll nicht vorhanden ist, dann Download SQLite.org. Tabelle TABELLE erstellen oder SQL-Befehl ändern. Welche Tabellen in einer SQLite Datenbank enthalten sind, kann mittels PRAGMA table_info(TABALLE) ermittelt werden. Verwende DBGrid > DataSource > ClientDataset > DatasetProvider > SQLDataset > SQLConnection. Siehe SQLite Datenbank Datensätze im DBGrid (Direkt) SQLConnection Parameter auf False setzen: SQLConnection1.Params.Values['FailIfMissin g'] := 'False'; oder Datenbankname prüfen. © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 41- SQLite3 mit Delphi XE3 03.09.2013 Zusammenfassung einige SQL-Befehle (Beispiele) Verwendete Variable: // Ergebnis SQL-Befehl SELECT, PRAGMA in TDataset speichern Var FDLSQLResults: TDataSet; // SQL-Befehl ausgeführt mittels SQLConnection.Execute Var LSQL: String; Tabelle Buecher erstellen, vorher löschen (falls vorhanden): LSQL := 'DROP TABLE IF EXISTS Buecher'; SQLConnection.Execute(LSQL, NIL); LSQL := 'CREATE TABLE Buecher (BuchID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, Titel VARCHAR(100) NOT NULL, AutorID INTEGER, ISBN VARCHAR(20));'; SQLConnection.Execute(LSQL, NIL); Buecher hinzufügen: LSQL := 'INSERT INTO Buecher (Titel, ISBN) VALUES ("Titel 1","ISBN1") '; SQLConnection.Execute(LSQL, NIL); SQLConnection.Execute(LSQL, NIL); Buchtitel aktualisieren: LSQL := 'UPDATE Buecher SET Titel="Buchtitel 2", ISBN="ISBN 2-2" WHERE Titel="Titel 2"'; SQLConnection.Execute(LSQL, NIL); Alle Buecher zeigen. Ergebnis in TDataSet FDLSQLResults: LSQL := 'SELECT * FROM Buecher;'; SQLConnection.Execute(LSQL, NIL, FDLSQLResults); Und weitere…: CREATE UNIQUE INDEX idx_isbn ON Buecher (isbn) DROP INDEX idx_isbn CREATE VIEW AlleBuecher AS SELECT * FROM Buecher DROP VIEW AlleBuecher Spezielle PRAGMA Befehle, wie Tabellenstruktur der Tabelle Buecher auflisten: PRAGMA Table_Info(Buecher); © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 42- SQLite3 mit Delphi XE3 03.09.2013 Referenz Beispieldatenbank Buecher.db SQL-Befehle DROP TABLE IF EXISTS Autoren; CREATE TABLE Autoren (AutorID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, Name VARCHAR(40), Beschreibung VARCHAR(255), Homepage VARCHAR(100)); DROP TABLE IF EXISTS Buecher; CREATE TABLE Buecher (BuchID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, Titel VARCHAR(100) NOT NULL, AutorID INTEGER, ISBN VARCHAR(20)); DROP TABLE IF EXISTS Log; CREATE TABLE Log (LogID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, Datum VARCHAR(20) NOT NULL, Info VARCHAR(255) NOT NULL); DROP TRIGGER IF EXISTS Buecher_I; CREATE TRIGGER Buecher_I AFTER INSERT ON Buecher BEGIN INSERT INTO Log(Datum, Info) VALUES (DATETIME('now'), 'Neu: ' || new.Titel); END; DROP TRIGGER IF EXISTS Buecher_U; CREATE TRIGGER Buecher_U AFTER UPDATE ON Buecher BEGIN INSERT INTO Log(Datum, Info) VALUES (DATETIME('now'), 'Geändert: ' || old.Titel || ' auf ' || new.Titel); END; DROP TRIGGER IF EXISTS Buecher_D; CREATE TRIGGER Buecher_D AFTER DELETE ON Buecher BEGIN INSERT INTO Log(Datum, Info) VALUES (DATETIME('now'), 'Gelöscht: ' || old.Titel); END; INSERT INTO Autoren (AutorID,Name) VALUES (NULL,'Hannes Nygaard'); INSERT INTO Autoren (AutorID,Name) VALUES (NULL,'Derek Meister'); INSERT INTO Autoren (AutorID,Name) VALUES (NULL,'Adler Olsen'); INSERT INTO Buecher (BuchID,Titel,AutorID,ISBN) VALUES (NULL,'Schwere Wetter',1,'9783897059207'); INSERT INTO Buecher (BuchID,Titel,AutorID,ISBN) VALUES (NULL,'Nebelfront',1,'9783954510269'); INSERT INTO Buecher (BuchID,Titel,AutorID,ISBN) VALUES (NULL,'Flutgrab',2,'9783442376476'); INSERT INTO Buecher (BuchID,Titel,AutorID,ISBN) VALUES (NULL,'Knochenwald',2,'9783442379323'); INSERT INTO Buecher (BuchID,Titel,AutorID,ISBN) VALUES (NULL,'Verachtung',3,'9783423280020'); INSERT INTO Buecher (BuchID,Titel,AutorID,ISBN) VALUES (NULL,'Erlösung',3,'9783423248525'); SELECT Autoren.Name,Buecher.Titel FROM Autoren, Buecher WHERE Autoren.AutorID=Buecher.AutorID; SELECT Buecher.BuchID,Buecher.Titel,Buecher.AutorID, Autoren.Name,Buecher.ISBN FROM Autoren, Buecher WHERE Autoren.AutorID = Buecher.AutorID © Robert W.B. Linn, Pinneberg, Germany. Internet: www.rwblinn.de Die Informationen in diese Anleitung wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Der Autor übernimmt keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene fehlerhafte Angaben und deren Folgen. - 43-