Difference between revisions of "Lazarus Database Tutorial/de"

From Lazarus wiki
Jump to navigationJump to search
m (Fixed syntax highlighting; deleted category included in page template)
 
(47 intermediate revisions by 14 users not shown)
Line 1: Line 1:
 
{{Lazarus Database Tutorial}}
 
{{Lazarus Database Tutorial}}
  
 +
Zurück zu den [[Additional information/de|Zusätzlichen Informationen]].<br>
 +
<br>
 
== Überblick ==
 
== Überblick ==
  
Dieses Tutorial handelt darüber, wie Lazarus mit einer Auswahl von existierenden Datenbanken zusammenarbeiten kann.
+
Das Thema dieses Tutorial ist, wie Lazarus mit einer Auswahl von existierenden Datenbanken zusammenarbeiten kann.
  
 
Bitte erweitern sie diesen Bereich.
 
Bitte erweitern sie diesen Bereich.
Line 9: Line 11:
 
== Lazarus und MySQL ==
 
== Lazarus und MySQL ==
  
=== MySQL zum Laufen bringen unter Linux oder Windows ===
+
=== MySQL unter Linux oder Windows zum Laufen bringen ===
Folgen sie den Anweisungen im MySQL Benutzerhandbuch. Stellen sie sicher, daß der mysqld Daemon zuverlässig läuft (zumindest bei Linux), und daß alle potentiellen Benutzer (inclusive root, mysql, sie selbst und jeder sonst, der es benötigen könnte) soviele Rechte (privileges) wie nötig hat, von so vielen Hosts wie nötig (inclusive 'localhost', dem lokalen Host Namen, jedem anderen Host in ihrem Netzwerk) so weit es mit der Sicherheit vereinbar ist. Auch haben viele benötigte Dateien im fpcsrc- und im lazarus-Ordner stark eingeschränkte Schreibrechte, die root erst ändern muss, wenn andere User damit arbeiten sollen. Mangelnde Schreibrechte in Units zeigt Lazarus durch die Fehlermeldung "Error while linking" an. Es ist wünschenswert, daß alle Benutzer inclusive root Passwörter haben. Testen sie die Wirkung des Datenbanksystems bei der Benutzung der Beispiele aus dem Handbuch, und prüfen sie daß alle Benutzer wirklich einen zuverlässigen Zugriff haben.
+
Folgen sie den Anweisungen im MySQL Benutzerhandbuch. Stellen sie sicher, dass der mysqld Daemon zuverlässig läuft (zumindest bei Linux), und dass alle potentiellen Benutzer (inclusive root, mysql, sie selbst und jeder sonst, der es benötigen könnte) so viele Rechte (privileges) wie nötig hat, von so vielen Hosts wie nötig (inclusive 'localhost', dem lokalen Host Namen, jedem anderen Host in ihrem Netzwerk) so weit es mit der Sicherheit vereinbar ist. Auch haben viele benötigte Dateien im fpcsrc- und im lazarus-Ordner stark eingeschränkte Schreibrechte, die root erst ändern muss, wenn andere User damit arbeiten sollen. Mangelnde Schreibrechte in Units zeigt Lazarus durch die Fehlermeldung "Error while linking" an. Es ist wünschenswert, dass alle Benutzer inclusive root Passwörter haben. Testen sie die Wirkung des Datenbanksystems bei der Benutzung der Beispiele aus dem Handbuch, und prüfen sie, dass alle Benutzer wirklich einen zuverlässigen Zugriff haben.
  
=== MySQL zum Laufen bringen für FPC im Textmodus ===
+
=== MySQL für FPC im Textmodus zum Laufen bringen ===
Es gibt ein Verzeichnis mit einem Beispielprogramm in $(fpc<b>src</b>dir)/packages/base/mysql/. Sie können das FPC Quellverzeichnis in Lazarus wie folgt finden: Environment menu -> Environment Options -> Paths tab -> FPC source directory. Mögliche Pfade für das mysql Verzeichnis sind /usr/share/fpcsrc/packages/base/mysql/ (rpm Installation) oder C:\lazarus\fpcsrc\packages\base\mysql\ (Windows). Dieses Verezichnis enthält auch die Units mysql.pp, mysql_com.pp und mysql_version.pp. Bevor sie das Testscript starten, müssen sie eine Datenbank mit dem Namen testdb anlegen: Tun sie dies, indem sie sich in den mysql Monitor einloggen (als root mit allen Rechten (privileges)) und das folgende SQL Statement eingeben
+
'''MySQL-Sourcen einbinden'''
 +
Es gibt ein Verzeichnis mit einem Beispielprogramm in $(fpc<b>src</b>dir)/packages/base/mysql/. Sie können das FPC Quellverzeichnis in Lazarus wie folgt finden: Werkzeuge -> Einstellungen -> Umgebung -> Dateien -> FPC-Quelltextverzeichnis. Mögliche Pfade für das mysql Verzeichnis sind /usr/share/fpcsrc/packages/base/mysql/ (rpm Installation) oder C:\lazarus\fpcsrc\packages\base\mysql\ (Windows). Dieses Verzeichnis enthält auch die Units mysql.pp, mysql_com.pp und mysql_version.pp.  
 +
 
 +
'''Datenbank vorbereiten'''
 +
Bevor sie das Testscript starten, müssen sie eine Datenbank mit dem Namen testdb anlegen: Tun sie dies, indem sie sich in den mysql Monitor einloggen (als root mit allen Rechten (privileges)) und das folgende SQL Statement eingeben
 
  CREATE DATABASE testdb;
 
  CREATE DATABASE testdb;
Dann müssen sie sicherstellen, daß alle relevanten Benutzer einen passenden Zugriff darauf haben
+
Dann müssen sie sicherstellen, dass alle relevanten Benutzer einen passenden Zugriff darauf haben
 
  GRANT ALL ON testdb TO johnny@localhost IDENTIFIED BY 'johnnyspassword';  
 
  GRANT ALL ON testdb TO johnny@localhost IDENTIFIED BY 'johnnyspassword';  
 
Es gibt ein Script namens mkdb, welches sie nun starten sollten:
 
Es gibt ein Script namens mkdb, welches sie nun starten sollten:
 
  sh ./mkdb
 
  sh ./mkdb
Dies wird wahrscheinlich fehlschlagen, weil das System keinem anonymen Benutzer den Zugriff auf die Datenbank erlauben wird. Ändern sie deshalb das Script mit einem Editor, so daß die Zeile, in der mysql aufgerufen wird, wie folgt aussieht:
+
Dies wird wahrscheinlich fehlschlagen, weil das System keinem anonymen Benutzer den Zugriff auf die Datenbank erlauben wird. Ändern sie deshalb das Script mit einem Editor, so dass die Zeile, in der mysql aufgerufen wird, wie folgt aussieht:
 
  mysql -u root -p  ${1-testdb} << EOF >/dev/null
 
  mysql -u root -p  ${1-testdb} << EOF >/dev/null
und versuchen sie es erneut zu starten. Geben sie ihr Passwort ein, wenn danach verlangt wird. Mit etwas Glück ist es ihnen gelungen, die Testdatenbank anzulegen: testen sie es (während sie im mysql Monitor eingeloggt sind) unter Verwendung des mysql Statements
+
und versuchen sie, es erneut zu starten. Geben sie ihr Passwort ein, wenn danach verlangt wird. Mit etwas Glück ist es ihnen gelungen, die Testdatenbank anzulegen: testen sie es (während sie im mysql Monitor eingeloggt sind) unter Verwendung der mysql Anweisung
 
  select * from FPdev;
 
  select * from FPdev;
 
Sie sollten eine Tabelle sehen, welche die ID, den Benutzernamen und die Emailadresse von einem der FPC Entwickler enthält.
 
Sie sollten eine Tabelle sehen, welche die ID, den Benutzernamen und die Emailadresse von einem der FPC Entwickler enthält.
  
Nun versuchen sie das Testprogramm testdb.pp zu starten (dieses muß evtl. noch kompiliert werden, und wird beinahe sicher beim ersten Versuch fehlschlagen!!).
+
'''Testprogramm starten'''
 +
Versuchen sie nun, das Testprogramm testdb.pp zu starten (dieses muss evtl. noch kompiliert werden, und wird beinahe sicher beim ersten Versuch fehlschlagen!!).
  
Ich habe herausgefunden, daß das Programm aus verschiedenen Gründen nicht mit mysql verbinden konnte:
+
Ich habe herausgefunden, dass das Programm aus verschiedenen Gründen nicht mit mysql verbinden konnte:
  
 
* Mein System (SuSE Linux v9.0) installiert mysql v4.0.15, nicht die Version 3, für welche das Package bestimmt war.   
 
* Mein System (SuSE Linux v9.0) installiert mysql v4.0.15, nicht die Version 3, für welche das Package bestimmt war.   
  
* Das Programm benötigt Benutzernamen und Passwörter um Zugriff auf die Datenbank zu erhalten.
+
* Das Programm benötigt Benutzernamen und Passwörter, um Zugriff auf die Datenbank zu erhalten.
  
* Der Compiler muß wissen, wo die mysql Bibliotheken zu finden sind. (Wenn sie die mysql Entwicklungs-Bibliotheken nicht installiert haben, dann tun sie es jetzt!)
+
* Der Compiler muss wissen, wo die mysql Bibliotheken zu finden sind. (Wenn sie die mysql Entwicklungs-Bibliotheken nicht installiert haben, dann tun sie es jetzt!)
  
Ich erzeugte eine Kopie von testdb.pp mit dem Namen trydb.pp, eher als das Original zu bearbeiten - das bedeutet, daß die originalen Dateien noch get fixed in späteren CVS Updates.
+
Ich erzeugte eine Kopie von testdb.pp mit dem Namen trydb.pp, eher als das Original zu bearbeiten - das bedeutet, dass die originalen Dateien in späteren CVS Updates noch bereinigt werden.
 
Ich kopierte auch die Dateien aus dem Unterverzeichnis mysql/ver40/ in das Haupt- mysql/ Unterverzeichnis, benannte sie in mysql_v4.pp, mysql_com_v4.pp und mysql_version_v4.pp um, um sicher zu sein, die Units mit jeder Datei entsprechend umzubenennen. Ich änderte die uses Anweisung in trydb.pp zu  
 
Ich kopierte auch die Dateien aus dem Unterverzeichnis mysql/ver40/ in das Haupt- mysql/ Unterverzeichnis, benannte sie in mysql_v4.pp, mysql_com_v4.pp und mysql_version_v4.pp um, um sicher zu sein, die Units mit jeder Datei entsprechend umzubenennen. Ich änderte die uses Anweisung in trydb.pp zu  
 
  uses mysql_v4
 
  uses mysql_v4
Line 45: Line 52:
 
  -Fl/lib;/usr/lib
 
  -Fl/lib;/usr/lib
 
Der folgende Schritt mag nicht notwendig sein, wenn die devel-Biblitheken installiert sind wie die Links für sie erzeugt sind, aber es kann nie schaden, es zu prüfen.
 
Der folgende Schritt mag nicht notwendig sein, wenn die devel-Biblitheken installiert sind wie die Links für sie erzeugt sind, aber es kann nie schaden, es zu prüfen.
Ich mußte den tatsächlichen Namen der mysqlclint Bibliothek finden im /usr/lib Verzeichnis und in meinem Fall mußte ich das shell Kommando eingeben:
+
Ich musste den tatsächlichen Namen der mysqlclint Bibliothek im /usr/lib Verzeichnis finden und in meinem Fall das folgende shell-Kommando eingeben:
 
  ln -s libmysqlclient.so.12.0.0 lmysqlclient
 
  ln -s libmysqlclient.so.12.0.0 lmysqlclient
um einen symbolischen Link zu erstellen, um FPC zu erlauben die Bibliothek zu finden.  Für ein gutes Maß erzeugte ich auch den Link
+
um einen symbolischen Link zu erstellen, um FPC zu erlauben, die Bibliothek zu finden.  Für ein gutes Maß erzeugte ich auch den Link
 
  ln -s libmysqlclient.so.12.0.0 mysqlclient
 
  ln -s libmysqlclient.so.12.0.0 mysqlclient
und plazierte einfache Links in verschiedenen anderen Verzeichnissen:  nicht unbedingt notwendig, aber für den Fall ...!
+
und plazierte einfache Links in verschiedenen anderen Verzeichnissen:  nicht unbedingt notwendig, aber für alle Fälle ...!
 
Einige Benutzer müssen evtl. den folgenden Link hinzufügen:
 
Einige Benutzer müssen evtl. den folgenden Link hinzufügen:
 
  ln -s libmysqlclient.so.12.0.0 libmysqlclient.so
 
  ln -s libmysqlclient.so.12.0.0 libmysqlclient.so
  
Ich modifizierte trydb.pp um Benutzerdetails einzubeziehen, zunächst durch Hinzufügen von host, Benutzer und Passwort als Konstanten:
+
Ich modifizierte trydb.pp, um Benutzerdetails einzubeziehen, zunächst indem ich host, Benutzer und Passwort als Konstanten hinzufügte:
  
 
  const
 
  const
Line 60: Line 67:
 
   passwd: Pchar = 'mypassword';
 
   passwd: Pchar = 'mypassword';
  
Ich habe auch herausgefunden, daß ich keine Verbindung bekam zu mysql mit der Benutzung des mysql_connect() Aufrufs, aber mit mysql_real_connect(), welches mehr Parameter hat. Um die Dinge weiter zu komplizieren, scheint die Anzahl der Parameter geändert werden zu müssen zwischen Version3 (wo es sieben sind) und Version4 (wo es acht sind). Vor der Benutzung von using mysql_real_connect mußte ich mysql_init() verwenden, welche nicht in der originalen mysql.pp zu finden ist aber in mysql_v4.pp.
+
Ich habe auch herausgefunden, dass ich keine Verbindung zu mysql mit der Benutzung des mysql_connect() Aufrufs bekam, aber mit mysql_real_connect(), das mehr Parameter hat. Um die Dinge weiter zu komplizieren, scheint die Anzahl der Parameter zwischen Version3 (wo es sieben sind) und Version4 (wo es acht sind) geändert werden zu müssen. Vor der Benutzung von using mysql_real_connect musste ich mysql_init() verwenden, das nicht in der originalen mysql.pp zu finden ist, aber in mysql_v4.pp.
  
 
Daher ist der Code für die Verbindung zur Datenbank jetzt:
 
Daher ist der Code für die Verbindung zur Datenbank jetzt:
  
 +
<syntaxhighlight lang=pascal>
 
  { einige extra Variablen}
 
  { einige extra Variablen}
 
  var
 
  var
Line 105: Line 113:
 
     end;
 
     end;
 
  {... wie die Originalinhalte von testdb.pp}
 
  {... wie die Originalinhalte von testdb.pp}
 
+
</syntaxhighlight>
  
 
Jetzt - sind sie bereit, um die Kompilierung von trydb.pp zu starten?
 
Jetzt - sind sie bereit, um die Kompilierung von trydb.pp zu starten?
Line 113: Line 121:
 
whoopee!  Ich erhielt die Auflistung der FPC Entwickler!
 
whoopee!  Ich erhielt die Auflistung der FPC Entwickler!
  
Einige zusätzliche Feinheiten:  Machen sie die Eingabe der Benutzerdetails und der mysql Befehle interaktiv, benutzen sie eher Variablen als Konstanten, und erlauben sie die Eingabe verschiedender SQL Befehle, bis wir den quit Befehl geben: schauen sie in der [[Lazarus Database Tutorial/TryDbpp|vollen Programmauflistung]] nach, wo Benutzerdetails von der Konsole aus eingegeben werden, und das Programm in eine Schleife geht, wo SQL Befehle von der Konsole aus eingegeben werden (ohne das abschliessende Semikolon) und die Antworten ausgedruckt werden, bis 'quit' über die Tastatur eingegeben wird.
+
Einige zusätzliche Feinheiten:  Machen sie die Eingabe der Benutzerdetails und der mysql Befehle interaktiv; benutzen sie eher Variablen als Konstanten und erlauben sie die Eingabe verschiedener SQL Befehle, bis wir den quit Befehl geben: schauen sie in der [[Lazarus Database Tutorial/TryDbpp|vollen Programmauflistung]] nach, wo Benutzerdetails von der Konsole aus eingegeben werden und das Programm in eine Schleife geht; wo SQL-Befehle von der Konsole aus eingegeben werden (ohne das abschließende Semikolon) und die Antworten ausgedruckt werden, bis 'quit' über die Tastatur eingegeben wird.
  
 
Siehe [[Lazarus Database Tutorial/SampleListing|Einfaches Konsole Listing]] .
 
Siehe [[Lazarus Database Tutorial/SampleListing|Einfaches Konsole Listing]] .
Line 119: Line 127:
 
=== Verbindung zu MySQL von einer Lazarus Anwendung aus ===
 
=== Verbindung zu MySQL von einer Lazarus Anwendung aus ===
  
Dieses Tutorial zeigt, wie man Lazarus bei einer MySQL Datenbank anmelden kann, und einfache Abfragen ausführen kann, lediglich unter Verwendung der Lazarus Grundkomponenten; es benutzt keine datensensitiven Komponenten, aber es illustriert die Prinzipien der Kopplung mit der Datenbank.
+
Dieses Tutorial zeigt, wie man Lazarus bei einer MySQL Datenbank anmelden und einfache Abfragen ausführen kann, lediglich unter Verwendung der Lazarus Grundkomponenten; es benutzt keine datensensitiven Komponenten, aber es illustriert die Prinzipien der Kopplung mit der Datenbank.
 +
 
 +
'''Achtung bei Windows:''' wir benötigen die libmysql.dll in der rightigen Version. Welche version benötigt wird erfahren Sie aus den Sourcen (üblicherweise aus der mysql_version.pp).
  
 
Erzeugen sie ein neues Projekt in Lazarus:
 
Erzeugen sie ein neues Projekt in Lazarus:
Line 127: Line 137:
 
Vergrößern sie das Formular bis es etwa die Hälfte ihres Bildschirms ausfüllt, dann benennen sie das Formular und seine Titelzeile (caption) in 'TryMySQL' um.
 
Vergrößern sie das Formular bis es etwa die Hälfte ihres Bildschirms ausfüllt, dann benennen sie das Formular und seine Titelzeile (caption) in 'TryMySQL' um.
  
Von der Standard Komponenten Palette plazieren sie drei Edit Felder oben links auf dem Formular, und plazieren sofort über jedem Feld ein Label.  Ändern sie die Namen und Captions zu 'Host' (und HostLLabel,HostEdit), 'UserName' (und UserLabel, UserEdit) und 'Password' (mit PasswdLabel und PasswdEdit). Alternativ können sie LabelledEdit Komponenten von der Additional Palette benutzen.
+
Von der Standard Komponentenpalette platzieren sie drei Edit Felder oben links auf dem Formular, und platzieren sofort über jedem Feld ein Label.  Ändern sie die Namen und Captions zu 'Host' (und HostLLabel,HostEdit), 'UserName' (und UserLabel, UserEdit) und 'Password' (mit PasswdLabel und PasswdEdit). Alternativ können sie LabelledEdit Komponenten von der Additional Palette benutzen.
  
Wählen sie die Passwd Edit box und finden sie die PasswordChar Eigenschaft:  ändern sie diese dies auf * oder ein anderes Zeichen, so dass ihrer Eingaben in diesem Feld nicht erscheinen, sondern nur eine Reihe von * erscheint. Stellen sie sicher, dass die Eigenschaft Text für jedes Edit Feld leer ist.  
+
Wählen sie das Passwd Editfeld und finden sie die PasswordChar Eigenschaft:  ändern sie diese dies auf * oder ein anderes Zeichen, so dass ihrer Eingaben in diesem Feld nicht erscheinen, sondern nur eine Reihe von * erscheint. Stellen sie sicher, dass die Eigenschaft Text für jedes Editfeld leer ist.  
  
Nun plazieren sie eine neues Edit Feld und Label oben rechts auf ihrem Formular.  Ändern sie die Label Caption zu 'Enter SQL Command' und nennen sie es CommandEdit.
+
Nun platzieren sie eine neues Edit Feld und Label oben rechts auf ihrem Formular.  Ändern sie die Label Caption zu 'Enter SQL Command' und nennen sie es CommandEdit.
  
 
Platzieren sie drei Buttons auf dem Formular:  zwei links unter den Edit Feldern, und einen rechts unter dem command Feld.
 
Platzieren sie drei Buttons auf dem Formular:  zwei links unter den Edit Feldern, und einen rechts unter dem command Feld.
Line 137: Line 147:
 
Benennen sie die Buttons auf der linken Seite 'Connect to Database' (ConnectButton) und 'Exit' (ExitButton) und den auf der rechten Seite 'Send Query' (QueryButton).
 
Benennen sie die Buttons auf der linken Seite 'Connect to Database' (ConnectButton) und 'Exit' (ExitButton) und den auf der rechten Seite 'Send Query' (QueryButton).
  
Plazieren sie ein großes Memo Feld mit Label und namen 'Results' (ResultMemo) unten rechts, um den meisten verfügbaren Platz auszufüllen. Finden sie seine ScrollBars Eigenschaft und wählen sie ssAutoBoth, so daß die Bildlaufleisten automatisch erscheinen wenn Text die Leerstellen füllt. Setzen sie die WordWrap Eigenschaft auf True.
+
Platzieren sie ein großes Memo Feld mit Label und Namen 'Results' (ResultMemo) unten rechts, um den meisten verfügbaren Platz auszufüllen. Finden sie seine ScrollBars Eigenschaft und wählen sie ssAutoBoth, so dass die Bildlaufleisten automatisch erscheinen wenn Text die Leerstellen füllt. Setzen sie die WordWrap Eigenschaft auf True.
  
Plazieren sie eine Status Bar (von der Common Controls Palette) am unteren Ende des Formulars, und setzen sein SimpleText Eigenschaft auf 'TryMySQL'.
+
Platzieren sie eine Status Bar (von der Common Controls Palette) am unteren Ende des Formulars, und setzen seine SimpleText Eigenschaft auf 'TryMySQL'.
  
Ein Screenshot des Formulars ist hier zu sehen: [http://lazarus-ccr.sourceforge.net/kbdata/trymysqldb.png Mysql Beispiel Screenshot]
+
Ein Bildschirmfoto des Formulars ist hier zu sehen: [http://lazarus-ccr.sourceforge.net/kbdata/trymysqldb.png Mysql Beispiel Screenshot]
  
Nun müssen wir einige Ereignis handler schreiben.
+
Nun müssen wir einige Ereignis-Handler schreiben.
  
Die drei Edit Boxen auf der linken sind für die Eingabe von Hostnamen, Benutzernamen und Passwort. Wenn diese zufriedenstellend eingegeben wurden, wird der Connect Button angeklickt.  Der OnCLick Ereignis handler für diesen Button beruht auf Teilen des Textmodus FPC Programms oberhalb.
+
Die drei Edit-Boxen auf der linken sind für die Eingabe von Hostnamen, Benutzernamen und Passwort. Wenn diese zufriedenstellend eingegeben wurden, wird der Connect Button angeklickt.  Der OnCLick Ereignis handler für diesen Button beruht auf Teilen des Textmodus FPC Programms oberhalb.
  
Die Antworten von der Datenbank können jetzt nicht mit den Pascal write oder writeln Anweisungen geschrieben werden: stattdessen, die Antworten müssen in Strings konvertiert und in einem Memo Feld angezeigt werden. Wohingegen die Pascal write und writeln Anweisungen geeignet sind, eine Menge von Typumformungen 'on the fly' durchzuführen, die Benutzung eines Memo Felds für die Textausgabe erfordert die explizite Konvertierung von Datentypen in die korrekte Form eines string, daher müssen Pchar Variablen in Strings konvertiert werden mit StrPas, und Integers müssen mit IntToStr konvertiert werden.   
+
Die Antworten von der Datenbank können jetzt nicht mit den Pascal ''write'' oder ''writeln'' Anweisungen geschrieben werden. Stattdessen müssen die Antworten in Strings konvertiert und in einem Memo Feld angezeigt werden. Wohingegen die Pascal ''write'' und ''writeln'' Anweisungen geeignet sind, eine Menge von Typumformungen 'on the fly' durchzuführen, die Benutzung eines Memo Felds für die Textausgabe erfordert die explizite Konvertierung von Datentypen in die korrekte Form eines string, daher müssen Pchar Variablen in Strings konvertiert werden mit ''StrPas'', und Integers müssen mit ''IntToStr'' konvertiert werden.   
  
 
Strings werden im Memo Feld angezeigt unter Verwendung von
 
Strings werden im Memo Feld angezeigt unter Verwendung von
Line 157: Line 167:
 
  end;
 
  end;
  
Der ConnectButton Ereignis handler wird daher:
+
Der ConnectButton Ereignis-handler wird daher:
  
 +
<syntaxhighlight lang=pascal>
 
  procedure TtrymysqlForm1.ConnectButtonClick(Sender: TObject);
 
  procedure TtrymysqlForm1.ConnectButtonClick(Sender: TObject);
 
  (* Verbinden zu MySQL unter Verwendung der Benutzerdaten von den Texteingabefeldern auf Main Form *)
 
  (* Verbinden zu MySQL unter Verwendung der Benutzerdaten von den Texteingabefeldern auf Main Form *)
Line 200: Line 211:
 
   end;
 
   end;
 
  end;
 
  end;
 +
</syntaxhighlight>
  
 +
Das Textfeld rechts erlaubt die Eingabe einer SQL-Anweisung, ohne abschließendes Semikolon. Wenn sie mit seinem Inhalt oder Schreibweise zufrieden sind, drücken sie den SendQuery-Button, und die Abfrage wird abgearbeitet, mit den Ergebnissen, die in das ResultsMemo-Feld geschrieben sind.
  
Das Textfeld zur rechten erlaubt die Eingabe einer SQL Anweisung, ohne einem abschließenden Semikolon; wenn sie mit seinem Inhalt oder Schreibweise zufrieden sind, drücken sie den SendQuery Button, und die Abfrage wird abgearbeitet, mit den Ergebnissen, die in das ResultsMemo Feld geschrieben sind.
+
Der SendQuery Ereignis-Handler basiert wieder auf der FPC Textmodus Version, abgesehen davon, dass eine explizite Typenkonversion erfolgen muss bevor Strings in der Box angezeigt werden.
 
 
Der SendQuery Ereignis handler basiert wieder auf der FPC Textmodus Version, ausgenommen that once again explicit type-conversion has to be done before strings are displayed in the box.
 
  
Ein Unterschied zu dem Textmodus FPC Programm ist, daß wenn eine Fehlerbedingung entdeckt wird, das Programm nicht stoppt und MySQL nicht geschlossen wird;  stattdessen, control is returned to the main form and an opportunity is given to correct the entry before the command is re-submitted.  Die Anwendung wird schließlich beendet (mit Schliessen von MySQL), wenn der Exit Button angeklickt wird.
+
Ein Unterschied zu dem Textmodus FPC Programm ist, dass das Programm nicht stoppt und MySQL nicht geschlossen wird, wenn eine Fehlerbedingung entdeckt wird. Stattdessen geht die Kontrolle an das Hauptformular zurück und eine Gelegenheit wird gegeben, den Eintrag zu berichtigen, bevor das Kommando neu eingereicht wird.  Die Anwendung wird schließlich beendet (mit Schliessen von MySQL), wenn der Exit-Button angeklickt wird.
  
 
Der Code für SendQuery folgt:
 
Der Code für SendQuery folgt:
  
 +
<syntaxhighlight lang=pascal>
 
  procedure TtrymysqlForm1.QueryButtonClick(Sender: TObject);
 
  procedure TtrymysqlForm1.QueryButtonClick(Sender: TObject);
 
  var
 
  var
Line 247: Line 259:
 
       end;
 
       end;
 
  end;
 
  end;
 
+
</syntaxhighlight>
  
 
Speichern sie ihr Projekt, und drücken Start -> Start
 
Speichern sie ihr Projekt, und drücken Start -> Start
  
 
==== Download des MYSQL Quelltextes ====
 
==== Download des MYSQL Quelltextes ====
Eine volle Auflistung des Programms ist hier verfügbar [http://lazarus-ccr.sourceforge.net/kbdata/mysqldemo.tar.gz Beispiel Quellcode]
+
Eine volle Auflistung des Programms gibt es hier [http://lazarus-ccr.sourceforge.net/kbdata/mysqldemo.tar.gz Beispiel Quellcode]
 +
 
 +
=== Lazarus, MySQL und UTF-8 ===
 +
''Das folgende könnte auch für andere Codepages/Zeichensätze erforderlich sein.''
 +
 
 +
UTF-8 Unicode ist eine praktische Kodierung eines Multibyte-Zeichensatzes, der es gestattet, mit mehrsprachigen Texten zu arbeiten, ohne dazu WideStrings einzusetzen. Er wird von den Lazarus-SQLdb-Komponenten und von MySQL seit Version 4.1 unterstützt durch die Auswahl eines geeigneten Zeichensatzes.
 +
 
 +
Allerdings gilt: ein einfaches Setzen dieser Kodierung als Vorgabe für Ihre Tabellen und die MySQL-Connection-Komponente resultiert in inkorrekter Speicherung und Rückgabe von UTF-8 Strings, wenn bestimmte akzentuierte/internationale Zeichen als Fragezeichen (?) angezeigt werden. Offensichtlich liegt die Ursache dafür darin, dass die MySQL-Client-Bibliothek mit dem Zeichensatz 'Latin1' als Vorgabe kompiliert wurde.
 +
 
 +
Um eine korrekte Kommunikation zwischen Lazarus, der MySQL-Client-Bibliothek und dem MySQL-Server zu aktivieren, müssen zwei zusätzliche Abfragen '''jedes Mal''' ausgeführt werden, wenn eine Verbindung zur Datenbank aufgebaut wird:
 +
<syntaxhighlight lang="sql">SET CHARACTER SET `utf8`</syntaxhighlight>
 +
und
 +
<syntaxhighlight lang="sql">SET NAMES 'utf8'</syntaxhighlight>
 +
Die erste Abfrage stellt sicher, dass Ihre Anwendung die Zeichenketten in korrekter Kodierung empfängt. Und die zweite weist MySQL an, nicht die Strings zu konvertieren, die es von Ihrer Anwendung erhält.
 +
 
 +
== Simple MySQL Demo Using the TMySQL50Connection Component ==
 +
 
 +
Here is code that functions as a quick demo to get up and running simply (tested on Win XP with Lighty2Go, though xampp would be just as suitable). libmysql.dll was put in the project and lazarus.exe directories (available from a directory in Lighty2Go or xampp - but ensure that you use the correct version of libmysql.dll to match the chosen TMySQL5xxConnection Component - for TMySQL50Connection use the version for MySQL 5.0 (1484kB) and this can connect fine to both MySQL 5.0 and MySQL 5.1 DBMSs. The 5.1 version of libmysql.dll will not function with TMySQL50Connection). There is no requirement to place any components on the form other than the three edit boxes, a memo box and a few buttons. You need to add mysql50conn and sqldb to the uses statement. The Lazarus component directory must be rw for the programmer. The mysql dbms here has a user 'root' with no password, and a database test1 with table tPerson which has three fields: personid (int), surname (varchar(40)) and dob (datetime). phpMyAdmin (in Lighty2Go) was used to create the db, table and fields and insert some sample data. Note that dates in phpMyAdmin should be entered YYYY-MM-DD, though the program created below will accept dates in the usual formats. The button btnTest must be clicked first as it creates the connection with the dbms. Note the line that applies updates - without this the changed or new data will not be written back to the db though they will be in memory and can be viewed using btnFirst and btnNext.
 +
 
 +
<syntaxhighlight lang=pascal>unit unt_db;
 +
// Example based on:
 +
// http://www.lazarus.freepascal.org/index.php?name=PNphpBB2&file=viewtopic&t=5761
 +
// from tpglemur on that forum
 +
{$mode objfpc}{$H+}
 +
interface
 +
uses
 +
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
 +
  mysql50conn, sqldb, StdCtrls;
 +
type
 +
  { TForm1 }
 +
  TForm1 = class(TForm)
 +
    btnTest: TButton;
 +
    btnNext: TButton;
 +
    btnFirst: TButton;
 +
    btnNew: TButton;
 +
    edtPersonID: TEdit;
 +
    edtSurname: TEdit;
 +
    edtDOB: TEdit;
 +
    Memo1: TMemo;
 +
    procedure btnFirstClick(Sender: TObject);
 +
    procedure btnNewClick(Sender: TObject);
 +
    procedure btnNextClick(Sender: TObject);
 +
    procedure btnTestClick(Sender: TObject);
 +
  private
 +
    { private declarations }
 +
    conn : TMySQL50Connection;
 +
    query : TSQLQuery;
 +
    transaction : TSQLTransaction;
 +
    procedure Display;
 +
  public
 +
    { public declarations }
 +
  end;
 +
var
 +
  Form1: TForm1;
 +
implementation
 +
{ TForm1 }
 +
procedure TForm1.btnTestClick(Sender: TObject);
 +
var
 +
  S: String;
 +
begin
 +
  conn := TMySQL50Connection.Create(nil);
 +
  query := TSQLQuery.Create(nil);
 +
  transaction := TSQLTransaction.Create(nil);
 +
  try
 +
    try
 +
      conn.HostName := '127.0.0.1';
 +
      conn.UserName := 'root';
 +
      conn.Password := '';
 +
      conn.DatabaseName := 'test1';
 +
      conn.Connected := True;
 +
      conn.Transaction := transaction;
 +
      query.DataBase := conn;
 +
      //query.ParseSQL := true; //line not needed - this is the default anyway
 +
      //query.ReadOnly := false; //line not needed - this is the default anyway
 +
      query.SQL.Text := 'select * from tperson';
 +
      query.Open;
 +
 
 +
      query.Last;
 +
      S := IntToStr(query.RecordCount) + #13#10;
 +
      query.First;
 +
 
 +
      while not query.EOF do
 +
      begin
 +
        S := S + query.FieldByName('surname').AsString + #13#10;
 +
        query.Next;
 +
      end;
 +
    finally
 +
      //query.Free;
 +
      //conn.Free;
 +
    end;
 +
  except
 +
    on E: Exception do
 +
      ShowMessage(E.message);
 +
  end;
 +
  Memo1.Text:= S;
 +
end;
 +
 
 +
procedure TForm1.Display;
 +
begin
 +
  edtPersonID.Text := query.FieldByName('personid').AsString;
 +
  edtSurname.Text := query.FieldByName('surname').AsString;
 +
  edtDOB.Text := query.FieldByName('dob').AsString;
 +
end;
 +
 
 +
procedure TForm1.btnFirstClick(Sender: TObject);
 +
begin
 +
  query.First;
 +
  Display;
 +
end;
 +
 
 +
procedure TForm1.btnNewClick(Sender: TObject);
 +
begin
 +
  query.Append;
 +
  query.FieldValues['personid'] := edtPersonID.Text;
 +
  query.FieldValues['surname'] := edtSurname.Text;
 +
  query.FieldValues['dob'] := edtDOB.Text;
 +
  query.Post; 
 +
  query.ApplyUpdates; //to apply update
 +
  //transaction.Commit; //line not needed
 +
end;
 +
 
 +
procedure TForm1.btnNextClick(Sender: TObject);
 +
begin
 +
  query.Next;
 +
  Display;
 +
end;
 +
 
 +
initialization
 +
  {$I unt_db.lrs}
 +
end.</syntaxhighlight>
 +
 
 +
Here is a version using the TMySQL50Connection, TSQLQuery, TSQLTransaction, TDatasource and TDBGrid components that have been placed on the form:
 +
 
 +
<syntaxhighlight lang=pascal>unit unt_mysql2;
 +
{$mode objfpc}{$H+}
 +
interface
 +
uses
 +
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
 +
  mysql50conn, sqldb, StdCtrls, db, DBGrids, DbCtrls;
 +
type
 +
  { TForm1 }
 +
  TForm1 = class(TForm)
 +
    btnConnect: TButton;
 +
    btnSave: TButton;
 +
    btnNext: TButton;
 +
    btnPrior: TButton;
 +
    Datasource1: TDatasource;
 +
    DBGrid1: TDBGrid;
 +
    Memo1: TMemo;
 +
    MySQL50Connection1: TMySQL50Connection;
 +
    SQLQuery1: TSQLQuery;
 +
    SQLTransaction1: TSQLTransaction;
 +
    procedure btnConnectClick(Sender: TObject);
 +
    procedure btnNextClick(Sender: TObject);
 +
    procedure btnPriorClick(Sender: TObject);
 +
    procedure btnSaveClick(Sender: TObject);
 +
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
 +
    procedure FormCreate(Sender: TObject);
 +
  private
 +
    { private declarations }
 +
  public
 +
    { public declarations }
 +
  end;
 +
var
 +
  Form1: TForm1;
 +
implementation
 +
{ TForm1 }
 +
 
 +
procedure TForm1.FormCreate(Sender: TObject);
 +
begin
 +
  //Set properties of components:
 +
  //(could be done in the Object Inspector)
 +
  MySQL50Connection1.HostName := '127.0.0.1';
 +
  MySQL50Connection1.UserName := 'root';
 +
  MySQL50Connection1.Password := '';
 +
  MySQL50Connection1.DatabaseName := 'test1';
 +
  MySQL50Connection1.Transaction := SQLTransaction1;
 +
  //SQLQuery1.ParseSQL := true; //line not needed - this is the default
 +
  //SQLQuery1.ReadOnly := false; //line not needed - this is the default
 +
  SQLQuery1.SQL.Text := 'select * from tperson';
 +
  SQLQuery1.Transaction := SQLTransaction1;
 +
  SQLQuery1.UpdateMode := upWhereChanged;
 +
  Datasource1.Dataset := SQLQuery1;
 +
  DBGrid1.DataSource := Datasource1;;
 +
end;
 +
 
 +
procedure TForm1.btnConnectClick(Sender: TObject);
 +
var
 +
S : string;
 +
begin
 +
  try
 +
    MySQL50Connection1.Connected := true;
 +
    SQLQuery1.Open;
 +
 
 +
    //Tests to see if all is OK:
 +
    SQLQuery1.Last;
 +
    S := IntToStr(SQLQuery1.RecordCount) + #13#10;
 +
    SQLQuery1.First;
 +
    while not SQLQuery1.EOF do
 +
    begin
 +
      S := S + SQLQuery1.FieldByName('surname').AsString + #13#10;
 +
      SQLQuery1.Next;
 +
    end;
 +
  except
 +
    on E: Exception do
 +
      ShowMessage(E.message);
 +
  end;
 +
  Memo1.Text:= S;
 +
end;
 +
 
 +
procedure TForm1.btnNextClick(Sender: TObject);
 +
begin
 +
  SQLQuery1.Next;
 +
end;
 +
 
 +
procedure TForm1.btnPriorClick(Sender: TObject);
 +
begin
 +
  SQLQuery1.Prior;
 +
end;
 +
 
 +
procedure TForm1.btnSaveClick(Sender: TObject);
 +
begin
 +
  SQLQuery1.ApplyUpdates;
 +
end;
 +
 
 +
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
 +
begin
 +
  //Required or get EDatabase error on close:
 +
  MySQL50Connection1.Connected := false;
 +
end;
 +
 
 +
initialization
 +
  {$I unt_mysql2.lrs}
 +
end.</syntaxhighlight>
 +
 
 +
== Lazarus und PostgreSQL ==
 +
 
 +
Dies ist ein sehr kurzes Tutorial, wie man mit Lazarus 0.9.12 oder höher eine Verbindung zu einer PostgreSQL-Datenbank aufbaut, lokal oder entfernt, mittels TPQConnection. Diese Komponente wird zu Lazarus hinzugefügt, wenn das Package 'lazarus/components/sqldb/sqldblaz.lpk' installiert wird.
 +
 
 +
Nach erfolgreicher Installation, befolgen Sie diese Schritte:
 +
 
 +
* Nehmen Sie eine PQConnection    aus dem Fach SQLdb
 +
* Nehmen Sie eine SQLQuery        aus dem Fach SQLdb
 +
* Nehmen Sie eine SQLTransaction  aus dem Fach SQLdb
 +
* Nehmen Sie eine DataSource      aus dem Fach DataAccess
 +
* Nehmen Sie ein  DBGrid          aus dem Fach DataControls
 +
 
 +
* In der PQConnection setzen Sie ein:
 +
** die Eigenschaft 'transaction' mit dem jeweiligen SQLTransaction-Object
 +
** den Datenbanknamen
 +
** HostName
 +
** UserName + password
 +
 
 +
* Überprüfen Sie, ob die SQLTransaction automatisch geändert wurde und jetzt auf die PQConnection zeigt
 +
 
 +
* In der SQLQuery setzen Sie ein:
 +
** die Eigenschaft 'transaction' mit dem jeweiligen Object
 +
** die Eigenschaft 'database' mit dem jeweiligen Object
 +
** SQL (irgendetwas wie 'select * from anytable')
 +
 
 +
* Im Objekt 'DataSource' setzen Sie die Eigenschaft 'DataSet' mit dem jeweiligen SQLQuery-Object
 +
 
 +
* Im DBGrid setzen Sie die Datenquelle als DataSource-Object
  
== Lazarus und Postgresql ==
+
Stellen Sie alles auf verbunden und aktiviert und das DBGrid sollte zur Entwurfszeit gefüllt werden.
 +
TDBText und TDBEdit scheinen zu funktionieren, aber zeigen (bei mir) nur die Daten.
  
Bitte schreiben sie mir!
+
Um die Inhalte der Datenbank zu ändern, rief ich die DB-Engine direkt mit dem folgenden Code auf:
 +
 
 +
<syntaxhighlight lang=pascal>try
 +
  sql:= 'UPDATE table SET setting=1';
 +
  PQDataBase.Connected:=True;
 +
  PQDataBase.ExecuteDirect('Begin Work;');
 +
  PQDataBase.ExecuteDirect(sql);
 +
  PQDataBase.ExecuteDirect('Commit Work;');
 +
  PQDataBase.Connected:=False;
 +
except
 +
  on E : EDatabaseError do
 +
    MemoLog.Append('DB ERROR:'+sql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message);
 +
  on E : Exception do
 +
    MemoLog.Append('ERROR:'+sql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message);
 +
end;</syntaxhighlight>
 +
 
 +
* Anmerkungen:
 +
** Getestet unter Windows, Lazarus 0.9.12 + PgSQL 8.3.1
 +
** Einige Tests unter Linux, Lazarus 0.9.12 and PgSQL 8.0.x
 +
 
 +
 
 +
* Installation und Fehler:
 +
** In der getesteten Version of Lazarus .12, haben die Felder vom Typ "text" und "numeric" Fehler
 +
** Ich verwendete problemlos: char fixed size, int und float8
 +
** Manchmal beseitigt ein Neustart von Lazarus dumme Fehler...
 +
** Nach einigen Fehlern bleiben die Transaktionen aktiv und sollten manuell deaktiviert werden
 +
** Von Lazarus gemachte Änderungen werden natürlich erst dann sichtbar, wenn die Transaktionen abgewickelt sind
 +
** Der integrierte Debugger scheint fehlerbehaftet (zumindest unter Windows) - manchmal hilft es, ihn außerhalb der IDE zu starten, um Fehler zu finden
 +
** Unter Linux werden bestimmte Fehlermeldungen über die Konsole ausgegeben -- starten Sie Ihr Programm in der Befehlszeile, manchmal finden Sie dort einige zusätzliche nützliche Infos zu Debuggen
 +
** Error: "Can not load Postgresql client. Is it installed (libpq.so) ?"
 +
*** Erweitern Sie den Pfad um die Suche nach libpq* aus der PostgreSQL-Installation.
 +
*** Unter Linux fügen Sie den Pfad zur Datei 'libpq.so' zum Abschnitt 'libraries' in Ihrer Datei /etc/fpc.cfg. Zum Beispiel: -Fl/usr/local/pgsql/lib
 +
*** Es ist vielleicht nötig einen symbolischen Link zu erzeugen: ln -s /usr/lib/pqsql.so.5 /usr/lib/pqsql.so
 +
***  Unter Windows fügen Sie diese Bibliotheken irgendwo in der Umgebungsvariablen PATH oder project dir ein
 +
***  Unter Windows kopierte ich alle DLLs aus meinem Verzeichnis 'C:\Program Files\PostgreSQL\8.1\bin' in ein anderes Verzeichnis im Pfad
 +
***  Oder fügen Sie dieses Verzeichnis 'postgres\bin' Ihrem Pfad hinzu
 +
 
 +
Ein gutes Beispiel darüber, wie man unter Windows Lazarus mit PostgreSQL verbindet ist [http://paginas.fe.up.pt/~asousa/wiki/doku.php?id=proj:lazarus_projects#easy_db easyDB].
  
 
== Lazarus und SQLite ==
 
== Lazarus und SQLite ==
Line 262: Line 574:
 
von Luiz Américo
 
von Luiz Américo
  
===Einführung===
+
Besuchen sie die [http://sqlite4fpc.yolasite.com/ sqlite4fpc Homepage]. Dort finden sie die API-Referenz und weitere Tutorials.
  
TSqliteDataset und TSqlite3Dataset sind eine TDataset Abkömmling Klasse, welche jeweils auf sqlite 2.8.x und 3.2.x Datenbanken zugreift. Nachstehend befindet sich eine Liste der hauptsächlichen Vorteile und Nachteile:
+
=== Einführung ===
 +
 
 +
TSqliteDataset und TSqlite3Dataset sind TDataset Abkömmling-Klassen, die jeweils auf sqlite 2.8.x und 3.x.x Datenbanken zugreifen. Nachstehend befindet sich eine Liste der wichtigsten Vor- und Nachteile:
  
 
Vorteile:
 
Vorteile:
Line 277: Line 591:
 
* Benötigt externe Datei (sqlite Bibliothek)
 
* Benötigt externe Datei (sqlite Bibliothek)
  
===Voraussetzungen===
+
=== Voraussetzungen ===
 
* Für sqlite2 Datenbanken:
 
* Für sqlite2 Datenbanken:
 
** fpc 2.0.0
 
** fpc 2.0.0
 
** Lazarus 0.9.10
 
** Lazarus 0.9.10
** sqlite Laufzeitbibliothek 2.8.15 oder höher (von www.sqlite.org)
+
** sqlite Laufzeitbibliothek 2.8.15 oder höher (von [http://www.sqlite.org www.sqlite.org])
  
 
* Für sqlite3 Datenbanken:
 
* Für sqlite3 Datenbanken:
 
** fpc 2.0.2
 
** fpc 2.0.2
 
** Lazarus 0.9.11 (SVN Revision 8443 oder höher)
 
** Lazarus 0.9.11 (SVN Revision 8443 oder höher)
** sqlite Laufzeitbibliothek 3.2.1 oder höher (von www.sqlite.org)
+
** sqlite Laufzeitbibliothek 3.2.1 oder höher (von [http://www.sqlite.org www.sqlite.org])
  
'''Bevor sie ein Lazarus Projekt beginnen, stellen sie sicher daß:'''
+
'''Bevor sie ein Lazarus Projekt beginnen, stellen sie sicher, dass:'''
 
* die sqlite Bibliothek im Systempfad (PATH) ist oder im Verzeichnis des executable
 
* die sqlite Bibliothek im Systempfad (PATH) ist oder im Verzeichnis des executable
* unter Linux, bringen sie cmem als erste Unit in den uses Abschnitt des Hauptprogramms
+
* unter Linux, bringen sie cmem als erste Unit in den uses-Abschnitt des Hauptprogramms
  
===Anwendung (grundlegende Verwendung)===
+
=== Anwendung (grundlegende Verwendung) ===
  
 
Installieren sie das Package aus dem /components/sqlite Verzeichnis (siehe Instruktionen [[Install_Packages/de|hier]])
 
Installieren sie das Package aus dem /components/sqlite Verzeichnis (siehe Instruktionen [[Install_Packages/de|hier]])
Line 300: Line 614:
 
* FileName: Pfad der sqlite Datei [benötigt]  
 
* FileName: Pfad der sqlite Datei [benötigt]  
 
* TableName: Name der Tabelle, die in der SQL Anweisung benutzt wird [benötigt]  
 
* TableName: Name der Tabelle, die in der SQL Anweisung benutzt wird [benötigt]  
* Sql: eine SQL select Anweisung [optional]  
+
* Sql: eine SQL ''select'' Anweisung [optional]  
  
 
'''Erzeugen einer Tabelle (Dataset)'''
 
'''Erzeugen einer Tabelle (Dataset)'''
  
Klicken sie doppelt auf das Komponenten Icon oder benutzen sie den 'Create Table' Punkt im Popup Menü, das erscheint, wenn sie mit der rechten Maustaste klicken.
+
Klicken sie doppelt auf das Komponenten-Icon oder benutzen sie den 'Create Table' Punkt im Popup-Menü, das erscheint, wenn sie mit der rechten Maustaste klicken.
Ein einfacher selbsterklärender Tabellen Editor wird eingeblendet.
+
Ein einfacher selbsterklärender Tabellen-Editor wird eingeblendet.
  
 
   Hier sind alle Feldtypen, die von TSqliteDataset und TSqlite3Dataset unterstützt werden:  
 
   Hier sind alle Feldtypen, die von TSqliteDataset und TSqlite3Dataset unterstützt werden:  
Line 324: Line 638:
 
'''Abrufen der Daten'''
 
'''Abrufen der Daten'''
  
Nach dem Erzeugen der Tabelle oder mit einer vorher erzeugten Tabelle, öffnen sie die Datenmenge mit der Open Methode.
+
Nach dem Erzeugen der Tabelle oder mit einer vorher erzeugten Tabelle, öffnen sie die Datenmenge mit der ''Open'' Methode.
Wenn die SQL Eigenschaft nicht gesetzt wurde, dann werden alle Datensätze von allen Feldern abgerufen, das selbe passiert, wenn sie SQL auf:
+
Wenn die SQL-Eigenschaft nicht gesetzt wurde, dann werden alle Datensätze von allen Feldern abgerufen, das selbe passiert, wenn sie SQL auf:
  
 
   SQL:='Select * from TABLENAME';  
 
   SQL:='Select * from TABLENAME';  
Line 333: Line 647:
 
'''Anwendung von Änderungen zur grundlegenden Datendatei'''
 
'''Anwendung von Änderungen zur grundlegenden Datendatei'''
  
Um die ApplyUpdates Funktion zu benutzen, muß der Datenbestand mindestens ein Feld enthalten, das die Anforderungen für einen Primary Key erfüllt (Werte müssen UNIQUE und nicht NULL sein).
+
Um die Funktion ApplyUpdates zu benutzen, muss der Datenbestand mindestens ein Feld enthalten, das die Anforderungen für einen Primary Key erfüllt (Werte müssen UNIQUE und nicht NULL sein).
  
 
Es ist möglich, dies auf zwei Wegen zu erreichen:
 
Es ist möglich, dies auf zwei Wegen zu erreichen:
  
* Setzen sie die PrimaryKey Eigenschaft auf den Namen eines Primary Key Feldes.
+
* Setzen sie die Eigenschaft PrimaryKey auf den Namen eines Primary Key Feldes.
* Fügen sie ein AutoInc Feld hinzu (dies ist einfacher seit TSqliteDataSet es automatisch als Primary Key behandelt)
+
* Fügen sie ein Feld AutoInc hinzu (dies ist einfacher seit TSqliteDataSet es automatisch als Primary Key behandelt)
  
Wenn eine oder zwei Bedingungen gesetzt sind rufen sie
+
Wenn eine oder zwei Bedingungen gesetzt sind, rufen sie
 
    
 
    
 
   ApplyUpdates;
 
   ApplyUpdates;
Line 348: Line 662:
 
PS1: Wenn beide Bedingungen gesetzt sind, wird das Feld entsprechend dem PrimaryKey genutzt, um die Updates anzuwenden.
 
PS1: Wenn beide Bedingungen gesetzt sind, wird das Feld entsprechend dem PrimaryKey genutzt, um die Updates anzuwenden.
  
PS2: Setzen von PrimaryKey auf ein Feld, das kein Primary Key ist, wird zu einem Verlust von Daten führen, wenn ApplyUpdates aufgerfen wird, daher stellen sie sicher, daß das gewählte Feld keinen Null Wert und Unique values enthält, bevor sie es benutzen.
+
PS2: Setzen von PrimaryKey auf ein Feld, das kein Primary Key ist, wird zu einem Verlust von Daten führen, wenn ApplyUpdates aufgerufen wird, daher stellen sie sicher, dass das gewählte Feld keinen Null Wert und Unique values enthält, bevor sie es benutzen.
  
===Bemerkungen===
+
=== Bemerkungen ===
  
* Obwohl es getestet wurde mit 10000 Datensätzen und problemlos funktionierte, TSqliteDataset hält alle Daten im Arbeitsspeicher, daher denken sie daran nur die notwendigen Daten abzurufen (hauptsächlich mit Memo Feldern).
+
* Obwohl es mit 10000 Datensätzen getestet wurde und problemlos funktionierte, hält TSqliteDataset alle Daten im Arbeitsspeicher. Denken sie daher daran, nur die notwendigen Daten abzurufen (hauptsächlich mit Memo Feldern).
 
* Die selbe Datendatei (Filename Eigenschaft) kann verschiedene Tabllen/Datasets hosten.
 
* Die selbe Datendatei (Filename Eigenschaft) kann verschiedene Tabllen/Datasets hosten.
* Verschiedene Datasets (unterschiedliche Kombinationen von Feldern) können erzeugt werden unter simultaner Nutzung der selben Tabelle.  
+
* Verschiedene Datasets (unterschiedliche Kombinationen von Feldern) können unter simultaner Nutzung der selben Tabelle erzeugt werden .  
* Es ist möglich die Daten zu filtern mit der WHERE Anweisung in SQL, das Dataset zu schliessen und wieder zu öffnen (oder die RefetchData Methode aufrufen). Aber in diesem Fall müssen die Reihenfolge und Anzahl der Felder gleich bleiben.  
+
* Es ist möglich, die Daten mit der ''WHERE'' Anweisung in SQL zu filtern, das Dataset zu schliessen und wieder zu öffnen (oder die Methode RefetchData aufrufen). Aber in diesem Fall müssen die Reihenfolge und Anzahl der Felder gleich bleiben.  
* Es ist auch möglich, komplexe SQL Anweisungen zu verwenden mittels Aliasen, Joins, Views bei mehrfachen Tabellen (denken sie daran, daß sie sich in der selben Datendatei befinden müssen), aber in diesem Fall wird ApplyUpdates nicht funktionieren. Wenn jemand komplexe Abfragen benutzen will und die Updates in die Datendatei einsetzen, soll er mir Schreiben und ich werde einige Hinweise geben, wie man das tut.
+
* Es ist auch möglich, komplexe SQL-Anweisungen zu verwenden mittels Aliasen, Joins, Views bei mehrfachen Tabellen (denken sie daran, dass sie sich in der selben Datendatei befinden müssen), aber in diesem Fall wird ApplyUpdates nicht funktionieren. Wenn jemand komplexe Abfragen benutzen und die Updates in die Datendatei einsetzen will, soll er mir schreiben und ich werde einige Hinweise geben, wie man das tut.
* Es ist erlaubt, den Dateinamen zu einer sqlite2.x Datendatei zu setzen, welche nicht von TSqliteDataset erzeugt wurde, aber einige Felder werden nicht den korrekten Feldtyp ermitteln. Diese werden als String Felder behandelt.
+
* Es ist erlaubt, den Dateinamen zu einer sqlite2.x Datendatei zu setzen, welche nicht von TSqliteDataset erzeugt wurde, aber einige Felder werden nicht den korrekten Feldtyp ermitteln. Diese werden als String-Felder behandelt.
  
Allgemeine Beispiele sind zu finden im fpc/fcl/db/sqlite CVS Verzeichnis
+
Allgemeine Beispiele sind zu finden im fpc/fcl/db/sqlite CVS-Verzeichnis
  
 
Luiz Américo
 
Luiz Américo
Line 370: Line 684:
 
== Lazarus und Interbase / Firebird ==
 
== Lazarus und Interbase / Firebird ==
  
Schauen sie auf [[Install Packages/de|Installation von Packages]] nach. Auf dieser Seite befindet sich ein erstes kleines Beispiel und Beschreibung, wie man eine Verbindung zu einem IB oder FB Server herstellt.
+
Schauen Sie auf [[Install Packages/de|Installation von Packages]] nach. Auf dieser Seite befindet sich ein erstes kleines Beispiel und eine Beschreibung, wie man eine Verbindung zu einem IB- oder FB-Server herstellt. Informationen zu Firebird gibt es auch hier [[Firebird]].
  
 
Funktioniert auch mit der neuesten Zeoslib (aus dem cvs).
 
Funktioniert auch mit der neuesten Zeoslib (aus dem cvs).
  
===FBLib Firebird Library===
+
===FBLib Firebird-Bibliothek===
  
[http://fblib.altervista.org/|FBLib] ist eine Open Source Bibliothek (nicht datensensitiv) für direkten Zugriff auf die Firebird relationale Datenbank von Borland Delphi / Kylix, Freepascal und Lazarus aus.
+
[http://fblib.altervista.org FBLib] ist eine Open-Source-Bibliothek für den direkten Zugriff auf das relationale Datenbanksystem Firebird. Funtioniert mit Borland Delphi, Kylix, Free Pascal und Lazarus.
  
Gegenwärtig sind folgende Features enthalten:
+
Folgende Merkmale sind aktuell enthalten:
  
* Direkter Zugriff auf Firebird 1.0.x 1.5.x Classic oder SuperServer
+
* Direkter Zugriff auf Firebird 1.0.x 1.5.x, 2.x Classic oder SuperServer
* Multiplattform [Win32,Gnu/Linux,FreeBSD)
+
* Multi-Plattform [Win32, Gnu/Linux, FreeBSD)
* Automatische Auswahl der Client Bibliothek 'fbclient' oder 'gds32'
+
* Automatische Auswahl der Klientenbibliothek 'fbclient' oder 'gds32'
* Abfragen (Queries) mit Parametern
+
* Abfragen mit Parametern
* Unterstützt SQL Dialekt 1/3
+
* Unterstützt den SQL-Dialekt 1/3
* LGPL Lizentvertrag
+
* LGPL Lizenz-Vereinbarung
* Extrahieren von Metadaten
+
* Extrahiert Metadaten
* Simple Script Parser
+
* Einfacher Skript-Parser
* Nur 100-150 KB werden zur finalen EXE hinzugefügt
+
* Fügt nur 100-150 KB zur ausführbaren EXE-Datei hinzu
* Unterstützt BLOB Felder
+
* Unterstützt BLOB-Felder
* Export von Daten als HTML SQL Script
+
* Exportiert Daten zu einem HTML SQL Script
* Service manager (backup,restore,gfix...)
+
* Service-Manager (Backup, Restore, gfix...)
* Events Alerter
+
* Ereignis-Benachrichtigung
  
Sie können die Dokumentation von der [http://fblib.altervista.org/|FBLib Webseite] downloaden.
+
Sie können die Dokumentation von der [http://fblib.altervista.org/ FBLib Website] herunterladen.
 +
 
 +
[http://www.firebirdnews.org/?p=1769 Hiere] finden Sie eine aktuelle Version. Oder Sie benutzen SVN: [https://tiopf.svn.sourceforge.net/svnroot/tiopf/3rdParty/FBLib/Trunk] (Tipp von [http://wiki.lazarus.freepascal.org/User:Guiosoft Guionardo])
  
 
== Lazarus und dBase ==
 
== Lazarus und dBase ==
Line 402: Line 718:
 
Sie können auch mit dem Besuch der [[Lazarus Tdbf Tutorial/de|TDbf Tutorial Seite]] anfangen.
 
Sie können auch mit dem Besuch der [[Lazarus Tdbf Tutorial/de|TDbf Tutorial Seite]] anfangen.
  
FPC enthält eine einfache Datenbank Komponente, welche ähnlich funktioniert wie die Delphi TTable Komponente, genannt "TDbf" ([http://tdbf.sourceforge.net/ TDbf Webseite]), die eine sehr elementare Teilmenge von Features für dBase Dateien bietet. Sie wird nicht standardmäßig installiert, so daß sie zunächst das Lazarus Package von dem "lazarus/components/tdbf" Verzeichnis installieren und ihre Lazarus IDE neu aufbauen müssen (rebuild).  Sie wird dann neben 'TDatasource' in ihrer Komponentenpalette erscheinen.
+
FPC enthält eine einfache Datenbank-Komponente, die ähnlich funktioniert wie die Delphi-Komponente TTable, genannt "TDbf" ([http://tdbf.sourceforge.net/ TDbf Webseite]), die eine sehr elementare Teilmenge von Features für dBase-Dateien bietet. Sie wird inzwischen standardmäßig installiert, so dass sie das Lazarus Package aus dem "lazarus/components/tdbf" Verzeichnis nicht mehr manuell installieren und ihre Lazarus IDE neu aufbauen müssen (rebuild).  Sie erscheint neben 'TDatasource' in ihrer Komponentenpalette.
  
Die TDbf Komponente hat einen Vorteil gegenüber anderen Datenbank Komponenten darin, daß sie keine Art von Datenbank-Laufzeit-engines benötigt, aber sie ist nicht die beste Option für große Datenbankanwendungen.
+
Die Komponente TDbf hat einen Vorteil gegenüber anderen Datenbank-Komponenten, dass sie keine Art von Datenbank-Laufzeit-engines benötigt. Sie ist aber nicht die beste Option für große Datenbankanwendungen.
  
Sie ist sehr einfach zu benutzen. Nehmen sie einfach eine TDbf und legen sie sie auf ihrem Formular ab, setzen den Laufzeit Pfad auf das Verzeichnis, wo sich ihre Datenbank Dateien befinden, setzen den Tabellennamen und verbinden sie mit ihrer TDatasource Komponente.
+
Sie ist sehr einfach zu benutzen. Nehmen sie einfach eine TDbf und legen sie sie auf ihrem Formular ab, setzen den Laufzeit-Pfad auf das Verzeichnis, wo sich ihre Datenbank-Dateien befinden, setzen den Tabellennamen und verbinden sie mit ihrer TDatasource-Komponente.
  
Wirkliche Funktionalität benötigt ein bißchen mehr Aufwand, wie auch immer. Wenn eine Tabelle nicht bereits schon existiert, müssen sie sie programmatisch erzeugen, es sei denn, es gibt einen kompatiblen Tabellen Designer, mit dem ich nicht vertraut bin.
+
Wirkliche Funktionalität benötigt ein bißchen mehr Aufwand, wie auch immer. Wenn eine Tabelle nicht bereits schon existiert, müssen sie sie per Programm erzeugen, es sei denn, es gibt einen kompatiblen Tabellen-Designer, mit dem ich nicht vertraut bin.
  
Der Versuch, eine nicht existierende Tabelle zu öffnen, wird einen Fehler erzeugen.  Tabellen können programmatisch erzeugt werden durch die Komponente nachdem der Laufzeit Pfad und der Tabellenname gesetzt wurden.
+
Der Versuch, eine nicht existierende Tabelle zu öffnen, wird einen Fehler erzeugen.  Tabellen können per Programm durch die Komponente erzeugt werden, sobald der Laufzeit-Pfad und der Tabellenname gesetzt wurden.
  
Zum Beispiel, um eine Tabelle mit dem Namen "dvds" zu erzeugen um ihre DVD Kollektion zu speichern würden sie sie auf ihrem Formular ablegen, den Laufzeit Pfad setzen und den Tabellennamen auf "dvds" setzen.  Die resultierende Datei heißt "dvds.dbf".
+
Ein Beispiel: Sie erzeugen eine Tabelle mit dem Namen "dvds", um ihre DVD-Kollektion zu speichern, in dem sie sie auf ihrem Formular ablegen, den Laufzeit-Pfad setzen und den Tabellennamen auf "dvds" setzen.  Die resultierende Datei heißt "dvds.dbf".
  
 
Fügen sie das Folgende in ihren Code ein:
 
Fügen sie das Folgende in ihren Code ein:
Line 425: Line 741:
 
     Dbf1.CreateTable;
 
     Dbf1.CreateTable;
  
Wenn dieser Code läuft, wird ihre DVD Kollektion Tabelle erzeugt. Danach werden alle datensensitiven Komponenten, die durch TDatasource mit dieser Komponente verbunden sind, einen einfachen Zugang zu den Daten erlauben.   
+
Wenn dieser Code läuft, wird ihre Tabelle DVD-Kollektion erzeugt. Danach werden alle datensensitiven Komponenten, die durch TDatasource mit dieser Komponente verbunden sind, einen einfachen Zugang zu den Daten erlauben.   
  
Das Hinzügen von Indexen ist einwenig unterschiedlich von ihrer typischen TTable. Es muß getan werden nachdem die Datenbank geöffnet wurde. Es ist auch die selbe Methode, die sie zum Erneuern der Indexe verwenden.  Zum Beispiel:
+
Das Hinzügen von Indexen ist ein wenig unterschiedlich von ihrer typischen TTable. Es muss getan werden, nachdem die Datenbank geöffnet wurde. Es ist auch die selbe Methode, die sie zum Erneuern der Indexe verwenden.  Zum Beispiel:
  
 
     Dbf1.Exclusive := True;
 
     Dbf1.Exclusive := True;
Line 435: Line 751:
 
     Dbf1.Close;
 
     Dbf1.Close;
  
Der erste (primary) Index ist eine Datei mit dem Namen "dvdsname.mdx" und der zweite ist die Datei "rating.ndx", daher müssen sie sorgfältig sein in einer Mehrfach Tabellen Datenbank, nicht den selben Dateinamen erneut zu verwenden.
+
Der erste (primary) Index ist eine Datei mit dem Namen "dvdsname.mdx" und der zweite ist die Datei "rating.ndx". Daher müssen sie aufpassen in einer Mehrfach-Tabellen Datenbank, den selben Dateinamen nicht zweimal zu verwenden.
 +
 
 +
Ich will versuchen, ein detaillierteres Beispiel zu einem späteren Zeitpunkt hinzuzufügen, aber hoffentlich wird dies jene 'alten' Delphi-Programmierer anspornen, Datenbankprogramme mit Lazarus zu schreiben!
 +
 
 +
== Verwendung von TSdfDataset und TFixedDataset ==
 +
 
 +
TSdfDataset and TFixedDataset are two simple datasets which offer a very simple textual storage format. These datasets are very convenient for small databases, because they are fully implemented as an object pascal unit, and thus require no external libraries, and because their textual format allows them to be easely edited with a text editor.
 +
 
 +
To start with this formats, a initial database file should be created. The format is very simple, so use a text editor to do this.
 +
 
 +
Below is a sample database for TSdfDataset. Note that the first line has the names of the fields and that we are using commas as separators:
 +
 
 +
<pre>
 +
ID,NAMEEN,NAMEPT,HEIGHT,WIDTH,PINS,DRAWINGCODE
 +
1,resistor,resistor,1,1,1,LINE
 +
2,capacitor,capacitor,1,1,1,LINE
 +
3,transistor npn,transistor npn
 +
</pre>
 +
 
 +
And here is an example database for using with TFixedDataset. Each record occupies a fixed amount of space, and if the field is smaller then it, spaces should be used to fill the remaining size.
 +
 
 +
<pre>
 +
Name = 15 chars; Surname = 15 chars; Tell = 10 chars; e_mail = 20 chars;
 +
Piet          Pompies                  piet@pompies.net   
 +
</pre>
 +
 
 +
=== Direkte Verwendung der Datasets ===
 +
 
 +
Sometimes it is useful to create the dataset and work with it completely in code, and the following code will do exactly this. Note some peculiarities of TSdfDataset/TFixedDataset:
 +
 
 +
* The lines in the database can have a maximum size of about 300. A fix is being researched.
 +
* It is necessary to add the field definitions. Some datasets are able to fill this information alone from the database file
 +
* One should set FirstLineAsSchema to true, to indicate that the first line includes the field names and positions
 +
* The Delimiter property holds the separator for the fields. It will not be possible to use this char in strings in the database. Similarly it will not be possible to have lineendings in the database because they mark the change between records. It's possible to overcome this by substituting the needed comma or line ending with another not often used char, like # for example. So that when showing the data on screen all # chars could be converted to line endings and the inverse when storing data back to the database. The ReplaceString routine is useful here.
 +
 
 +
<syntaxhighlight lang=pascal>
 +
constructor TComponentsDatabase.Create;
 +
begin
 +
  inherited Create;
 +
 
 +
  FDataset := TSdfDataset.Create(nil);
 +
  FDataset.FileName := vConfigurations.ComponentsDBFile;
 +
 
 +
  // Not necessary with TSdfDataset
 +
//  FDataset.TableName := STR_DB_COMPONENTS_TABLE;
 +
//  FDataset.PrimaryKey := STR_DB_COMPONENTS_ID;
 +
 
 +
  // Adds field definitions
 +
  FDataset.FieldDefs.Add('ID', ftString);
 +
  FDataset.FieldDefs.Add('NAMEEN', ftString);
 +
  FDataset.FieldDefs.Add('NAMEPT', ftString);
 +
  FDataset.FieldDefs.Add('HEIGHT', ftString);
 +
  FDataset.FieldDefs.Add('WIDTH', ftString);
 +
  FDataset.FieldDefs.Add('PINS', ftString);
 +
  FDataset.FieldDefs.Add('DRAWINGCODE', ftString);
 +
 
 +
  // Necessary for TSdfDataset
 +
  FDataset.Delimiter := ',';
 +
  FDataset.FirstLineAsSchema := True;
 +
 
 +
  FDataset.Active := True;
 +
 
 +
  // Sets the initial record
 +
  CurrentRecNo := 1;
 +
  FDataset.First;
 +
end;
 +
</syntaxhighlight>
 +
 
 +
When using TSdfDataset directly be careful that althought it is implemented, RecNo does not work correctly, neither for setting nor for reading. The standard movimentation routines like First, Next, Prior and Last work correctly, so it's possible to use them to implement a replacement for RecNo. Keep a variable somewhere called CurrentRecNo which will hold the current RecNo value. Remember that this variable will have the same convention as RecNo, so the first record has number 1. After activating the database initialize the database to the first record with TSdfDataset.First and with CurrentRecNo := 1
 +
 
 +
<syntaxhighlight lang=pascal>
 +
{@@
 +
  Moves to the desired record using TDataset.Next and TDataset.Prior
 +
  Avoids using TDataset.RecNo which doesn't work in all datasets
 +
 
 +
  @param AID Indicates the record number. The first record has number 1
 +
}
 +
procedure TComponentsDatabase.GoToRec(AID: Integer);
 +
begin
 +
  // We are before the desired record, move forward
 +
  if CurrentRecNo < AID then
 +
  begin
 +
    while (not FDataset.EOF) and (CurrentRecNo < AID) do
 +
    begin
 +
      FDataset.Next;
 +
      FDataset.CursorPosChanged;
 +
      Inc(CurrentRecNo);
 +
    end;
 +
  end
 +
  // We are after the desired record, move back
 +
  else if CurrentRecNo > AID  then
 +
  begin
 +
    while (CurrentRecNo >= 1) and (CurrentRecNo > AID) do
 +
    begin
 +
      FDataset.Prior;
 +
      FDataset.CursorPosChanged;
 +
      Dec(CurrentRecNo);
 +
    end;
 +
  end;
 +
end;
 +
</syntaxhighlight>
 +
 
 +
=== Verwendung mit datensensitiven Komponenten ===
  
Ich will versuchen, ein detaillierteres Beispiel zu einem späteren Zeitpunkt hinzuzufügen, aber hoffentlich wird dies jene 'alten' Delphi Programmierer in Gang bringen mit Datenbanken in Lazarus!
+
==Siehe auch==
  
== Übersetzungen von dieser Seite ==
+
* [[Databases/de|Datenbanken (deutsch)]] - Startseite für Datenbankanwendungen mit Lazarus
* [[Lazarus Database Tutorial/es| Spanisch]] von Eduardo Lopez
+
* [[Databases in Lazarus/de|Datenbanken in Lazarus (deutsch)]] - Ein Überblick über die Verwendung von Datenbanken in Lazarus
* [[Lazarus Database Tutorial/nl| Niederländisch]]
+
* [[How to write in-memory database applications in Lazarus/FPC]] - In-Memory Datenbank-Anwendungen
 +
* [[MySQLDatabases/de|MySQLDatenbanken (deutsch)]] - Erstellung einer Datenbankanwendung unter Verwendung von MySQL
 +
* [[Zeos tutorial/de| Zeos Tutorial (deutsch)]] - Verwendung der Zeos Komponenten
 +
* [[Lazarus Tdbf Tutorial]] - Tutorial über einfache Datenbankentwicklung mittels der [http://tdbf.sf.net TDbf]-Komponente (von Micha Nelissen)
 +
* [[Lazarus DB Faq/de|Lazarus DB Faq (deutsch]] - FAQ über Datenbanken in Lazarus
 +
* [[Firebird]] - Erstellen einer Datenbankanwendung für Firebird
 +
* [[ODBCConn]] - Verbindung mit ODBC-Datenbanken
 +
* [[MS Access]] - Wie man auf eine Microsoft Access Datenbank zugreift
  
== Verwandte Links ==
+
==Externe Links==
[[Databases/de| Erstellen von Datenbankanwendungen mit Lazarus unter Verwendung der DB-Unit]]<br>
 
[[MySQLDatabases| Erstellung einer Datenbankanwendung unter Verwendung von MySQL]]<br>
 
[[Zeos tutorial/de| Verwendung der Zeos Komponenten]]
 
  
==Mitwirkende und Änderungen==
+
* [http://pdo.sourceforge.net Pascal Data Objects] - eine Datenbank API die mit FPC und Delphi funktioniert und die nativen MySQL-Bibliotheken für Version 4.1 und 5.0 sowie Firebird SQL 1.5 und 2.0 verwendet.  Sie wurde durch PHP's PDO-Klasse angeregt.
Diese Seite wurde konvertiert von der epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=LazarusDatabase Version].
+
* [http://lazaruszeos.blogspot.com Zeos+SQLite Tutorial] - Ein gutes Tutorial mit Screenshots. Es erklärt wie Sie SQLite und Zeos benutzen. Allerdings auf Spanisch - (Google translate hilft bei der Übersetzung ins Deutsche)

Latest revision as of 23:46, 18 February 2020

Deutsch (de) English (en) español (es) français (fr) Bahasa Indonesia (id) italiano (it) 日本語 (ja) Nederlands (nl) português (pt) русский (ru) 中文(中国大陆)‎ (zh_CN) 中文(台灣)‎ (zh_TW)

Zurück zu den Zusätzlichen Informationen.

Überblick

Das Thema dieses Tutorial ist, wie Lazarus mit einer Auswahl von existierenden Datenbanken zusammenarbeiten kann.

Bitte erweitern sie diesen Bereich.

Lazarus und MySQL

MySQL unter Linux oder Windows zum Laufen bringen

Folgen sie den Anweisungen im MySQL Benutzerhandbuch. Stellen sie sicher, dass der mysqld Daemon zuverlässig läuft (zumindest bei Linux), und dass alle potentiellen Benutzer (inclusive root, mysql, sie selbst und jeder sonst, der es benötigen könnte) so viele Rechte (privileges) wie nötig hat, von so vielen Hosts wie nötig (inclusive 'localhost', dem lokalen Host Namen, jedem anderen Host in ihrem Netzwerk) so weit es mit der Sicherheit vereinbar ist. Auch haben viele benötigte Dateien im fpcsrc- und im lazarus-Ordner stark eingeschränkte Schreibrechte, die root erst ändern muss, wenn andere User damit arbeiten sollen. Mangelnde Schreibrechte in Units zeigt Lazarus durch die Fehlermeldung "Error while linking" an. Es ist wünschenswert, dass alle Benutzer inclusive root Passwörter haben. Testen sie die Wirkung des Datenbanksystems bei der Benutzung der Beispiele aus dem Handbuch, und prüfen sie, dass alle Benutzer wirklich einen zuverlässigen Zugriff haben.

MySQL für FPC im Textmodus zum Laufen bringen

MySQL-Sourcen einbinden Es gibt ein Verzeichnis mit einem Beispielprogramm in $(fpcsrcdir)/packages/base/mysql/. Sie können das FPC Quellverzeichnis in Lazarus wie folgt finden: Werkzeuge -> Einstellungen -> Umgebung -> Dateien -> FPC-Quelltextverzeichnis. Mögliche Pfade für das mysql Verzeichnis sind /usr/share/fpcsrc/packages/base/mysql/ (rpm Installation) oder C:\lazarus\fpcsrc\packages\base\mysql\ (Windows). Dieses Verzeichnis enthält auch die Units mysql.pp, mysql_com.pp und mysql_version.pp.

Datenbank vorbereiten Bevor sie das Testscript starten, müssen sie eine Datenbank mit dem Namen testdb anlegen: Tun sie dies, indem sie sich in den mysql Monitor einloggen (als root mit allen Rechten (privileges)) und das folgende SQL Statement eingeben

CREATE DATABASE testdb;

Dann müssen sie sicherstellen, dass alle relevanten Benutzer einen passenden Zugriff darauf haben

GRANT ALL ON testdb TO johnny@localhost IDENTIFIED BY 'johnnyspassword'; 

Es gibt ein Script namens mkdb, welches sie nun starten sollten:

sh ./mkdb

Dies wird wahrscheinlich fehlschlagen, weil das System keinem anonymen Benutzer den Zugriff auf die Datenbank erlauben wird. Ändern sie deshalb das Script mit einem Editor, so dass die Zeile, in der mysql aufgerufen wird, wie folgt aussieht:

mysql -u root -p  ${1-testdb} << EOF >/dev/null

und versuchen sie, es erneut zu starten. Geben sie ihr Passwort ein, wenn danach verlangt wird. Mit etwas Glück ist es ihnen gelungen, die Testdatenbank anzulegen: testen sie es (während sie im mysql Monitor eingeloggt sind) unter Verwendung der mysql Anweisung

select * from FPdev;

Sie sollten eine Tabelle sehen, welche die ID, den Benutzernamen und die Emailadresse von einem der FPC Entwickler enthält.

Testprogramm starten Versuchen sie nun, das Testprogramm testdb.pp zu starten (dieses muss evtl. noch kompiliert werden, und wird beinahe sicher beim ersten Versuch fehlschlagen!!).

Ich habe herausgefunden, dass das Programm aus verschiedenen Gründen nicht mit mysql verbinden konnte:

  • Mein System (SuSE Linux v9.0) installiert mysql v4.0.15, nicht die Version 3, für welche das Package bestimmt war.
  • Das Programm benötigt Benutzernamen und Passwörter, um Zugriff auf die Datenbank zu erhalten.
  • Der Compiler muss wissen, wo die mysql Bibliotheken zu finden sind. (Wenn sie die mysql Entwicklungs-Bibliotheken nicht installiert haben, dann tun sie es jetzt!)

Ich erzeugte eine Kopie von testdb.pp mit dem Namen trydb.pp, eher als das Original zu bearbeiten - das bedeutet, dass die originalen Dateien in späteren CVS Updates noch bereinigt werden. Ich kopierte auch die Dateien aus dem Unterverzeichnis mysql/ver40/ in das Haupt- mysql/ Unterverzeichnis, benannte sie in mysql_v4.pp, mysql_com_v4.pp und mysql_version_v4.pp um, um sicher zu sein, die Units mit jeder Datei entsprechend umzubenennen. Ich änderte die uses Anweisung in trydb.pp zu

uses mysql_v4

und die Anweisung in mysql_v4.pp zu

uses mysql_com_v4

Ich fügte eine Zeile zu /etc/fpc.cfg hinzu, um auf meine Bibliotheken zu zeigen:

-Fl/lib;/usr/lib

Der folgende Schritt mag nicht notwendig sein, wenn die devel-Biblitheken installiert sind wie die Links für sie erzeugt sind, aber es kann nie schaden, es zu prüfen. Ich musste den tatsächlichen Namen der mysqlclint Bibliothek im /usr/lib Verzeichnis finden und in meinem Fall das folgende shell-Kommando eingeben:

ln -s libmysqlclient.so.12.0.0 lmysqlclient

um einen symbolischen Link zu erstellen, um FPC zu erlauben, die Bibliothek zu finden. Für ein gutes Maß erzeugte ich auch den Link

ln -s libmysqlclient.so.12.0.0 mysqlclient

und plazierte einfache Links in verschiedenen anderen Verzeichnissen: nicht unbedingt notwendig, aber für alle Fälle ...! Einige Benutzer müssen evtl. den folgenden Link hinzufügen:

ln -s libmysqlclient.so.12.0.0 libmysqlclient.so

Ich modifizierte trydb.pp, um Benutzerdetails einzubeziehen, zunächst indem ich host, Benutzer und Passwort als Konstanten hinzufügte:

const
  host : Pchar= 'localhost';
  user : Pchar= 'myusername';
  passwd: Pchar = 'mypassword';

Ich habe auch herausgefunden, dass ich keine Verbindung zu mysql mit der Benutzung des mysql_connect() Aufrufs bekam, aber mit mysql_real_connect(), das mehr Parameter hat. Um die Dinge weiter zu komplizieren, scheint die Anzahl der Parameter zwischen Version3 (wo es sieben sind) und Version4 (wo es acht sind) geändert werden zu müssen. Vor der Benutzung von using mysql_real_connect musste ich mysql_init() verwenden, das nicht in der originalen mysql.pp zu finden ist, aber in mysql_v4.pp.

Daher ist der Code für die Verbindung zur Datenbank jetzt:

 { einige extra Variablen}
 var
   alloc : PMYSQL;
  
 {Teil des Hauptprogramms}
  
 begin
  if paramcount=1 then
    begin
    Dummy:=Paramstr(1)+#0;
    DataBase:=@Dummy[1];
    end;
  
 Writeln ('Allocating Space...');
  alloc := mysql_init(PMYSQL(@qmysql));
  Write ('Connecting to MySQL...');
  sock :=  mysql_real_connect(alloc, host, user, passwd, database, 0, nil, 0);
  if sock=Nil then
    begin
    Writeln (stderr,'Couldn''t connect to MySQL.');
    Writeln (stderr, 'Error was: ', mysql_error(@qmysql));
    halt(1);
    end;
  Writeln ('Done.');
  Writeln ('Connection data:');
 {$ifdef Unix}
  writeln ('Mysql_port      : ',mysql_port);
  writeln ('Mysql_unix_port : ',mysql_unix_port);
 {$endif}
  writeln ('Host info       : ',mysql_get_host_info(sock));
  writeln ('Server info     : ',mysql_stat(sock));
  writeln ('Client info     : ',mysql_get_client_info);
  
  Writeln ('Selecting Database ',DataBase,'...');
  if mysql_select_db(sock,DataBase) < 0 then
    begin
    Writeln (stderr,'Couldn''t select database ',Database);
    Writeln (stderr,mysql_error(sock));
    halt (1);
    end;
 {... wie die Originalinhalte von testdb.pp}

Jetzt - sind sie bereit, um die Kompilierung von trydb.pp zu starten?

 fpc trydb

Erfolg! Jetzt starten sie es:

 ./trydb

whoopee! Ich erhielt die Auflistung der FPC Entwickler!

Einige zusätzliche Feinheiten: Machen sie die Eingabe der Benutzerdetails und der mysql Befehle interaktiv; benutzen sie eher Variablen als Konstanten und erlauben sie die Eingabe verschiedener SQL Befehle, bis wir den quit Befehl geben: schauen sie in der vollen Programmauflistung nach, wo Benutzerdetails von der Konsole aus eingegeben werden und das Programm in eine Schleife geht; wo SQL-Befehle von der Konsole aus eingegeben werden (ohne das abschließende Semikolon) und die Antworten ausgedruckt werden, bis 'quit' über die Tastatur eingegeben wird.

Siehe Einfaches Konsole Listing .

Verbindung zu MySQL von einer Lazarus Anwendung aus

Dieses Tutorial zeigt, wie man Lazarus bei einer MySQL Datenbank anmelden und einfache Abfragen ausführen kann, lediglich unter Verwendung der Lazarus Grundkomponenten; es benutzt keine datensensitiven Komponenten, aber es illustriert die Prinzipien der Kopplung mit der Datenbank.

Achtung bei Windows: wir benötigen die libmysql.dll in der rightigen Version. Welche version benötigt wird erfahren Sie aus den Sourcen (üblicherweise aus der mysql_version.pp).

Erzeugen sie ein neues Projekt in Lazarus:

Projekt -> Neues Projekt -> Anwendung

Ein neues automatisch erzeugtes Formular wird erscheinen.

Vergrößern sie das Formular bis es etwa die Hälfte ihres Bildschirms ausfüllt, dann benennen sie das Formular und seine Titelzeile (caption) in 'TryMySQL' um.

Von der Standard Komponentenpalette platzieren sie drei Edit Felder oben links auf dem Formular, und platzieren sofort über jedem Feld ein Label. Ändern sie die Namen und Captions zu 'Host' (und HostLLabel,HostEdit), 'UserName' (und UserLabel, UserEdit) und 'Password' (mit PasswdLabel und PasswdEdit). Alternativ können sie LabelledEdit Komponenten von der Additional Palette benutzen.

Wählen sie das Passwd Editfeld und finden sie die PasswordChar Eigenschaft: ändern sie diese dies auf * oder ein anderes Zeichen, so dass ihrer Eingaben in diesem Feld nicht erscheinen, sondern nur eine Reihe von * erscheint. Stellen sie sicher, dass die Eigenschaft Text für jedes Editfeld leer ist.

Nun platzieren sie eine neues Edit Feld und Label oben rechts auf ihrem Formular. Ändern sie die Label Caption zu 'Enter SQL Command' und nennen sie es CommandEdit.

Platzieren sie drei Buttons auf dem Formular: zwei links unter den Edit Feldern, und einen rechts unter dem command Feld.

Benennen sie die Buttons auf der linken Seite 'Connect to Database' (ConnectButton) und 'Exit' (ExitButton) und den auf der rechten Seite 'Send Query' (QueryButton).

Platzieren sie ein großes Memo Feld mit Label und Namen 'Results' (ResultMemo) unten rechts, um den meisten verfügbaren Platz auszufüllen. Finden sie seine ScrollBars Eigenschaft und wählen sie ssAutoBoth, so dass die Bildlaufleisten automatisch erscheinen wenn Text die Leerstellen füllt. Setzen sie die WordWrap Eigenschaft auf True.

Platzieren sie eine Status Bar (von der Common Controls Palette) am unteren Ende des Formulars, und setzen seine SimpleText Eigenschaft auf 'TryMySQL'.

Ein Bildschirmfoto des Formulars ist hier zu sehen: Mysql Beispiel Screenshot

Nun müssen wir einige Ereignis-Handler schreiben.

Die drei Edit-Boxen auf der linken sind für die Eingabe von Hostnamen, Benutzernamen und Passwort. Wenn diese zufriedenstellend eingegeben wurden, wird der Connect Button angeklickt. Der OnCLick Ereignis handler für diesen Button beruht auf Teilen des Textmodus FPC Programms oberhalb.

Die Antworten von der Datenbank können jetzt nicht mit den Pascal write oder writeln Anweisungen geschrieben werden. Stattdessen müssen die Antworten in Strings konvertiert und in einem Memo Feld angezeigt werden. Wohingegen die Pascal write und writeln Anweisungen geeignet sind, eine Menge von Typumformungen 'on the fly' durchzuführen, die Benutzung eines Memo Felds für die Textausgabe erfordert die explizite Konvertierung von Datentypen in die korrekte Form eines string, daher müssen Pchar Variablen in Strings konvertiert werden mit StrPas, und Integers müssen mit IntToStr konvertiert werden.

Strings werden im Memo Feld angezeigt unter Verwendung von

procedure ShowString (S : string);
(* zeigt einen String in einem Memo Feld an *)
begin
       trymysqlForm1.ResultsMemo.Lines.Add (S)
end;

Der ConnectButton Ereignis-handler wird daher:

 procedure TtrymysqlForm1.ConnectButtonClick(Sender: TObject);
 (* Verbinden zu MySQL unter Verwendung der Benutzerdaten von den Texteingabefeldern auf Main Form *)
 var strg: string;
  
 begin
  
  dummy1 :=  trymysqlForm1.HostEdit.text+#0;
  host := @dummy1[1];
  dummy2 := trymysqlForm1.UserEdit.text+#0;
  user := @dummy2[1] ;
  dummy3 := trymysqlForm1.PasswdEdit.text+#0;
  passwd := @dummy3[1] ;

  alloc := mysql_init(PMYSQL(@qmysql));
  sock :=  mysql_real_connect(alloc, host, user, passwd, database, 0, nil, 0);
  if sock=Nil then
    begin
      strg :='Couldn''t connect to MySQL.'; showstring (strg);
      Strg :='Error was: '+ StrPas(mysql_error(@qmysql)); showstring (strg);
   end
    else
    begin
      trymysqlForm1.statusBar1.simpletext := 'Connected to MySQL';
      strg := 'Now choosing database : ' + database; showstring (strg);
 {$ifdef Unix}
      strg :='Mysql_port      : '+ IntToStr(mysql_port); showstring (strg);
      strg :='Mysql_unix_port : ' + StrPas(mysql_unix_port); showstring (strg);
 {$endif}
      Strg :='Host info       : ' + StrPas(mysql_get_host_info(sock));
      showstring (strg);
      Strg :='Server info     : ' + StrPas(mysql_stat(sock)); showstring (strg);
      Strg :='Client info     : ' + Strpas(mysql_get_client_info);  showstring (strg);
  
      trymysqlForm1.statusbar1.simpletext := 'Selecting Database ' + DataBase +'...';
  if mysql_select_db(sock,DataBase) < 0 then
  begin
    strg :='Couldn''t select database '+ Database; ShowString (strg);
    Strg := mysql_error(sock); ShowString (strg);
  end
  end;
 end;

Das Textfeld rechts erlaubt die Eingabe einer SQL-Anweisung, ohne abschließendes Semikolon. Wenn sie mit seinem Inhalt oder Schreibweise zufrieden sind, drücken sie den SendQuery-Button, und die Abfrage wird abgearbeitet, mit den Ergebnissen, die in das ResultsMemo-Feld geschrieben sind.

Der SendQuery Ereignis-Handler basiert wieder auf der FPC Textmodus Version, abgesehen davon, dass eine explizite Typenkonversion erfolgen muss bevor Strings in der Box angezeigt werden.

Ein Unterschied zu dem Textmodus FPC Programm ist, dass das Programm nicht stoppt und MySQL nicht geschlossen wird, wenn eine Fehlerbedingung entdeckt wird. Stattdessen geht die Kontrolle an das Hauptformular zurück und eine Gelegenheit wird gegeben, den Eintrag zu berichtigen, bevor das Kommando neu eingereicht wird. Die Anwendung wird schließlich beendet (mit Schliessen von MySQL), wenn der Exit-Button angeklickt wird.

Der Code für SendQuery folgt:

 procedure TtrymysqlForm1.QueryButtonClick(Sender: TObject);
 var
  dumquery, strg: string;
 begin
      dumquery := TrymysqlForm1.CommandEdit.text;
      dumquery := dumquery+#0;
      query := @dumquery[1];
      trymysqlForm1.statusbar1.simpletext := 'Executing query : '+ dumQuery +'...';
      strg := 'Executing query : ' + dumQuery; showstring (strg);
      if (mysql_query(sock,Query) < 0) then
      begin
        Strg :='Query failed '+ StrPas(mysql_error(sock)); showstring (strg);
      end
      else
      begin
        recbuf := mysql_store_result(sock);
        if RecBuf=Nil then
        begin
          Strg :='Query returned nil result.'; showstring (strg);
        end
        else
        begin
          strg :='Number of records returned  : ' + IntToStr(mysql_num_rows (recbuf));
          Showstring (strg);
          Strg :='Number of fields per record : ' + IntToStr(mysql_num_fields(recbuf));
          showstring (strg);
          rowbuf := mysql_fetch_row(recbuf);
          while (rowbuf <>nil) do
          begin
               Strg :='(Id: '+ rowbuf[0]+', Name: ' + rowbuf[1]+ ', Email : ' +
                rowbuf[2] +')';
               showstring (strg);
               rowbuf := mysql_fetch_row(recbuf);
          end;
        end;
      end;
 end;

Speichern sie ihr Projekt, und drücken Start -> Start

Download des MYSQL Quelltextes

Eine volle Auflistung des Programms gibt es hier Beispiel Quellcode

Lazarus, MySQL und UTF-8

Das folgende könnte auch für andere Codepages/Zeichensätze erforderlich sein.

UTF-8 Unicode ist eine praktische Kodierung eines Multibyte-Zeichensatzes, der es gestattet, mit mehrsprachigen Texten zu arbeiten, ohne dazu WideStrings einzusetzen. Er wird von den Lazarus-SQLdb-Komponenten und von MySQL seit Version 4.1 unterstützt durch die Auswahl eines geeigneten Zeichensatzes.

Allerdings gilt: ein einfaches Setzen dieser Kodierung als Vorgabe für Ihre Tabellen und die MySQL-Connection-Komponente resultiert in inkorrekter Speicherung und Rückgabe von UTF-8 Strings, wenn bestimmte akzentuierte/internationale Zeichen als Fragezeichen (?) angezeigt werden. Offensichtlich liegt die Ursache dafür darin, dass die MySQL-Client-Bibliothek mit dem Zeichensatz 'Latin1' als Vorgabe kompiliert wurde.

Um eine korrekte Kommunikation zwischen Lazarus, der MySQL-Client-Bibliothek und dem MySQL-Server zu aktivieren, müssen zwei zusätzliche Abfragen jedes Mal ausgeführt werden, wenn eine Verbindung zur Datenbank aufgebaut wird:

SET CHARACTER SET `utf8`

und

SET NAMES 'utf8'

Die erste Abfrage stellt sicher, dass Ihre Anwendung die Zeichenketten in korrekter Kodierung empfängt. Und die zweite weist MySQL an, nicht die Strings zu konvertieren, die es von Ihrer Anwendung erhält.

Simple MySQL Demo Using the TMySQL50Connection Component

Here is code that functions as a quick demo to get up and running simply (tested on Win XP with Lighty2Go, though xampp would be just as suitable). libmysql.dll was put in the project and lazarus.exe directories (available from a directory in Lighty2Go or xampp - but ensure that you use the correct version of libmysql.dll to match the chosen TMySQL5xxConnection Component - for TMySQL50Connection use the version for MySQL 5.0 (1484kB) and this can connect fine to both MySQL 5.0 and MySQL 5.1 DBMSs. The 5.1 version of libmysql.dll will not function with TMySQL50Connection). There is no requirement to place any components on the form other than the three edit boxes, a memo box and a few buttons. You need to add mysql50conn and sqldb to the uses statement. The Lazarus component directory must be rw for the programmer. The mysql dbms here has a user 'root' with no password, and a database test1 with table tPerson which has three fields: personid (int), surname (varchar(40)) and dob (datetime). phpMyAdmin (in Lighty2Go) was used to create the db, table and fields and insert some sample data. Note that dates in phpMyAdmin should be entered YYYY-MM-DD, though the program created below will accept dates in the usual formats. The button btnTest must be clicked first as it creates the connection with the dbms. Note the line that applies updates - without this the changed or new data will not be written back to the db though they will be in memory and can be viewed using btnFirst and btnNext.

unit unt_db;
// Example based on:
// http://www.lazarus.freepascal.org/index.php?name=PNphpBB2&file=viewtopic&t=5761
// from tpglemur on that forum
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
  mysql50conn, sqldb, StdCtrls;
type
  { TForm1 }
  TForm1 = class(TForm)
    btnTest: TButton;
    btnNext: TButton;
    btnFirst: TButton;
    btnNew: TButton;
    edtPersonID: TEdit;
    edtSurname: TEdit;
    edtDOB: TEdit;
    Memo1: TMemo;
    procedure btnFirstClick(Sender: TObject);
    procedure btnNewClick(Sender: TObject);
    procedure btnNextClick(Sender: TObject);
    procedure btnTestClick(Sender: TObject);
  private
    { private declarations }
    conn : TMySQL50Connection;
    query : TSQLQuery;
    transaction : TSQLTransaction;
    procedure Display;
  public
    { public declarations }
  end;
var
  Form1: TForm1;
implementation
{ TForm1 }
procedure TForm1.btnTestClick(Sender: TObject);
var
  S: String;
begin
  conn := TMySQL50Connection.Create(nil);
  query := TSQLQuery.Create(nil);
  transaction := TSQLTransaction.Create(nil);
  try
    try
      conn.HostName := '127.0.0.1';
      conn.UserName := 'root';
      conn.Password := '';
      conn.DatabaseName := 'test1';
      conn.Connected := True;
      conn.Transaction := transaction;
      query.DataBase := conn;
      //query.ParseSQL := true; //line not needed - this is the default anyway
      //query.ReadOnly := false; //line not needed - this is the default anyway
      query.SQL.Text := 'select * from tperson';
      query.Open;

      query.Last;
      S := IntToStr(query.RecordCount) + #13#10;
      query.First;

      while not query.EOF do
      begin
        S := S + query.FieldByName('surname').AsString + #13#10;
        query.Next;
      end;
    finally
      //query.Free;
      //conn.Free;
    end;
  except
    on E: Exception do
      ShowMessage(E.message);
  end;
  Memo1.Text:= S;
end;

procedure TForm1.Display;
begin
  edtPersonID.Text := query.FieldByName('personid').AsString;
  edtSurname.Text := query.FieldByName('surname').AsString;
  edtDOB.Text := query.FieldByName('dob').AsString;
end;

procedure TForm1.btnFirstClick(Sender: TObject);
begin
  query.First;
  Display;
end;

procedure TForm1.btnNewClick(Sender: TObject);
begin
  query.Append;
  query.FieldValues['personid'] := edtPersonID.Text;
  query.FieldValues['surname'] := edtSurname.Text;
  query.FieldValues['dob'] := edtDOB.Text;
  query.Post;  
  query.ApplyUpdates; //to apply update
  //transaction.Commit; //line not needed
end;

procedure TForm1.btnNextClick(Sender: TObject);
begin
  query.Next;
  Display;
end;

initialization
  {$I unt_db.lrs}
end.

Here is a version using the TMySQL50Connection, TSQLQuery, TSQLTransaction, TDatasource and TDBGrid components that have been placed on the form:

unit unt_mysql2;
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
  mysql50conn, sqldb, StdCtrls, db, DBGrids, DbCtrls;
type
  { TForm1 }
  TForm1 = class(TForm)
    btnConnect: TButton;
    btnSave: TButton;
    btnNext: TButton;
    btnPrior: TButton;
    Datasource1: TDatasource;
    DBGrid1: TDBGrid;
    Memo1: TMemo;
    MySQL50Connection1: TMySQL50Connection;
    SQLQuery1: TSQLQuery;
    SQLTransaction1: TSQLTransaction;
    procedure btnConnectClick(Sender: TObject);
    procedure btnNextClick(Sender: TObject);
    procedure btnPriorClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end; 
var
  Form1: TForm1; 
implementation
{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  //Set properties of components:
  //(could be done in the Object Inspector)
  MySQL50Connection1.HostName := '127.0.0.1';
  MySQL50Connection1.UserName := 'root';
  MySQL50Connection1.Password := '';
  MySQL50Connection1.DatabaseName := 'test1';
  MySQL50Connection1.Transaction := SQLTransaction1;
  //SQLQuery1.ParseSQL := true; //line not needed - this is the default
  //SQLQuery1.ReadOnly := false; //line not needed - this is the default
  SQLQuery1.SQL.Text := 'select * from tperson';
  SQLQuery1.Transaction := SQLTransaction1;
  SQLQuery1.UpdateMode := upWhereChanged;
  Datasource1.Dataset := SQLQuery1;
  DBGrid1.DataSource := Datasource1;;
end;

procedure TForm1.btnConnectClick(Sender: TObject);
var
 S : string;
begin
  try
    MySQL50Connection1.Connected := true;
    SQLQuery1.Open;

    //Tests to see if all is OK:
    SQLQuery1.Last;
    S := IntToStr(SQLQuery1.RecordCount) + #13#10;
    SQLQuery1.First;
    while not SQLQuery1.EOF do
    begin
      S := S + SQLQuery1.FieldByName('surname').AsString + #13#10;
      SQLQuery1.Next;
    end;
  except
    on E: Exception do
      ShowMessage(E.message);
  end;
  Memo1.Text:= S;
end;

procedure TForm1.btnNextClick(Sender: TObject);
begin
  SQLQuery1.Next;
end;

procedure TForm1.btnPriorClick(Sender: TObject);
begin
  SQLQuery1.Prior;
end;

procedure TForm1.btnSaveClick(Sender: TObject);
begin
  SQLQuery1.ApplyUpdates;
end;

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  //Required or get EDatabase error on close:
  MySQL50Connection1.Connected := false;
end;

initialization
  {$I unt_mysql2.lrs}
end.

Lazarus und PostgreSQL

Dies ist ein sehr kurzes Tutorial, wie man mit Lazarus 0.9.12 oder höher eine Verbindung zu einer PostgreSQL-Datenbank aufbaut, lokal oder entfernt, mittels TPQConnection. Diese Komponente wird zu Lazarus hinzugefügt, wenn das Package 'lazarus/components/sqldb/sqldblaz.lpk' installiert wird.

Nach erfolgreicher Installation, befolgen Sie diese Schritte:

  • Nehmen Sie eine PQConnection aus dem Fach SQLdb
  • Nehmen Sie eine SQLQuery aus dem Fach SQLdb
  • Nehmen Sie eine SQLTransaction aus dem Fach SQLdb
  • Nehmen Sie eine DataSource aus dem Fach DataAccess
  • Nehmen Sie ein DBGrid aus dem Fach DataControls
  • In der PQConnection setzen Sie ein:
    • die Eigenschaft 'transaction' mit dem jeweiligen SQLTransaction-Object
    • den Datenbanknamen
    • HostName
    • UserName + password
  • Überprüfen Sie, ob die SQLTransaction automatisch geändert wurde und jetzt auf die PQConnection zeigt
  • In der SQLQuery setzen Sie ein:
    • die Eigenschaft 'transaction' mit dem jeweiligen Object
    • die Eigenschaft 'database' mit dem jeweiligen Object
    • SQL (irgendetwas wie 'select * from anytable')
  • Im Objekt 'DataSource' setzen Sie die Eigenschaft 'DataSet' mit dem jeweiligen SQLQuery-Object
  • Im DBGrid setzen Sie die Datenquelle als DataSource-Object

Stellen Sie alles auf verbunden und aktiviert und das DBGrid sollte zur Entwurfszeit gefüllt werden. TDBText und TDBEdit scheinen zu funktionieren, aber zeigen (bei mir) nur die Daten.

Um die Inhalte der Datenbank zu ändern, rief ich die DB-Engine direkt mit dem folgenden Code auf:

try
  sql:= 'UPDATE table SET setting=1';
  PQDataBase.Connected:=True;
  PQDataBase.ExecuteDirect('Begin Work;');
  PQDataBase.ExecuteDirect(sql);
  PQDataBase.ExecuteDirect('Commit Work;');
  PQDataBase.Connected:=False;
except
  on E : EDatabaseError do
    MemoLog.Append('DB ERROR:'+sql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message);
  on E : Exception do
    MemoLog.Append('ERROR:'+sql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message);
end;
  • Anmerkungen:
    • Getestet unter Windows, Lazarus 0.9.12 + PgSQL 8.3.1
    • Einige Tests unter Linux, Lazarus 0.9.12 and PgSQL 8.0.x


  • Installation und Fehler:
    • In der getesteten Version of Lazarus .12, haben die Felder vom Typ "text" und "numeric" Fehler
    • Ich verwendete problemlos: char fixed size, int und float8
    • Manchmal beseitigt ein Neustart von Lazarus dumme Fehler...
    • Nach einigen Fehlern bleiben die Transaktionen aktiv und sollten manuell deaktiviert werden
    • Von Lazarus gemachte Änderungen werden natürlich erst dann sichtbar, wenn die Transaktionen abgewickelt sind
    • Der integrierte Debugger scheint fehlerbehaftet (zumindest unter Windows) - manchmal hilft es, ihn außerhalb der IDE zu starten, um Fehler zu finden
    • Unter Linux werden bestimmte Fehlermeldungen über die Konsole ausgegeben -- starten Sie Ihr Programm in der Befehlszeile, manchmal finden Sie dort einige zusätzliche nützliche Infos zu Debuggen
    • Error: "Can not load Postgresql client. Is it installed (libpq.so) ?"
      • Erweitern Sie den Pfad um die Suche nach libpq* aus der PostgreSQL-Installation.
      • Unter Linux fügen Sie den Pfad zur Datei 'libpq.so' zum Abschnitt 'libraries' in Ihrer Datei /etc/fpc.cfg. Zum Beispiel: -Fl/usr/local/pgsql/lib
      • Es ist vielleicht nötig einen symbolischen Link zu erzeugen: ln -s /usr/lib/pqsql.so.5 /usr/lib/pqsql.so
      • Unter Windows fügen Sie diese Bibliotheken irgendwo in der Umgebungsvariablen PATH oder project dir ein
      • Unter Windows kopierte ich alle DLLs aus meinem Verzeichnis 'C:\Program Files\PostgreSQL\8.1\bin' in ein anderes Verzeichnis im Pfad
      • Oder fügen Sie dieses Verzeichnis 'postgres\bin' Ihrem Pfad hinzu

Ein gutes Beispiel darüber, wie man unter Windows Lazarus mit PostgreSQL verbindet ist easyDB.

Lazarus und SQLite

von Luiz Américo

Besuchen sie die sqlite4fpc Homepage. Dort finden sie die API-Referenz und weitere Tutorials.

Einführung

TSqliteDataset und TSqlite3Dataset sind TDataset Abkömmling-Klassen, die jeweils auf sqlite 2.8.x und 3.x.x Datenbanken zugreifen. Nachstehend befindet sich eine Liste der wichtigsten Vor- und Nachteile:

Vorteile:

  • Flexibilität: Programmier können wählen, ob sie die SQL Sprache verwenden oder nicht, erlaubt ihnen mit einfachen Tabellenlayouts zu arbeiten oder jedem komplexen Layout, welches SQL ermöglicht.
  • Automatisches Datenbank Update: Kein Bedarf, die Datenbank manuell mit SQL Anweisungen zu updaten, eine einzelne Methode erledigt dies.
  • Schnelligkeit: Es puffert die Daten im Arbeitsspeicher, was das Browsen im Datenbestand schnell macht.
  • Keine Server Installation/Konfiguration: einfach zusammen verfrachten mit der sqlite dynamic Bibliothek.

Nachteile

  • Benötigt externe Datei (sqlite Bibliothek)

Voraussetzungen

  • Für sqlite2 Datenbanken:
    • fpc 2.0.0
    • Lazarus 0.9.10
    • sqlite Laufzeitbibliothek 2.8.15 oder höher (von www.sqlite.org)
  • Für sqlite3 Datenbanken:
    • fpc 2.0.2
    • Lazarus 0.9.11 (SVN Revision 8443 oder höher)
    • sqlite Laufzeitbibliothek 3.2.1 oder höher (von www.sqlite.org)

Bevor sie ein Lazarus Projekt beginnen, stellen sie sicher, dass:

  • die sqlite Bibliothek im Systempfad (PATH) ist oder im Verzeichnis des executable
  • unter Linux, bringen sie cmem als erste Unit in den uses-Abschnitt des Hauptprogramms

Anwendung (grundlegende Verwendung)

Installieren sie das Package aus dem /components/sqlite Verzeichnis (siehe Instruktionen hier)

Zur Entwicklungszeit setzen sie die folgenen Eigenschaften:

  • FileName: Pfad der sqlite Datei [benötigt]
  • TableName: Name der Tabelle, die in der SQL Anweisung benutzt wird [benötigt]
  • Sql: eine SQL select Anweisung [optional]

Erzeugen einer Tabelle (Dataset)

Klicken sie doppelt auf das Komponenten-Icon oder benutzen sie den 'Create Table' Punkt im Popup-Menü, das erscheint, wenn sie mit der rechten Maustaste klicken. Ein einfacher selbsterklärender Tabellen-Editor wird eingeblendet.

 Hier sind alle Feldtypen, die von TSqliteDataset und TSqlite3Dataset unterstützt werden: 
 
 Integer
 AutoInc
 String
 Memo
 Bool 
 Float
 Word
 DateTime
 Date
 Time
 LargeInt
 Currency
 

Abrufen der Daten

Nach dem Erzeugen der Tabelle oder mit einer vorher erzeugten Tabelle, öffnen sie die Datenmenge mit der Open Methode. Wenn die SQL-Eigenschaft nicht gesetzt wurde, dann werden alle Datensätze von allen Feldern abgerufen, das selbe passiert, wenn sie SQL auf:

 SQL:='Select * from TABLENAME'; 

setzen.

Anwendung von Änderungen zur grundlegenden Datendatei

Um die Funktion ApplyUpdates zu benutzen, muss der Datenbestand mindestens ein Feld enthalten, das die Anforderungen für einen Primary Key erfüllt (Werte müssen UNIQUE und nicht NULL sein).

Es ist möglich, dies auf zwei Wegen zu erreichen:

  • Setzen sie die Eigenschaft PrimaryKey auf den Namen eines Primary Key Feldes.
  • Fügen sie ein Feld AutoInc hinzu (dies ist einfacher seit TSqliteDataSet es automatisch als Primary Key behandelt)

Wenn eine oder zwei Bedingungen gesetzt sind, rufen sie

 ApplyUpdates;

auf.

PS1: Wenn beide Bedingungen gesetzt sind, wird das Feld entsprechend dem PrimaryKey genutzt, um die Updates anzuwenden.

PS2: Setzen von PrimaryKey auf ein Feld, das kein Primary Key ist, wird zu einem Verlust von Daten führen, wenn ApplyUpdates aufgerufen wird, daher stellen sie sicher, dass das gewählte Feld keinen Null Wert und Unique values enthält, bevor sie es benutzen.

Bemerkungen

  • Obwohl es mit 10000 Datensätzen getestet wurde und problemlos funktionierte, hält TSqliteDataset alle Daten im Arbeitsspeicher. Denken sie daher daran, nur die notwendigen Daten abzurufen (hauptsächlich mit Memo Feldern).
  • Die selbe Datendatei (Filename Eigenschaft) kann verschiedene Tabllen/Datasets hosten.
  • Verschiedene Datasets (unterschiedliche Kombinationen von Feldern) können unter simultaner Nutzung der selben Tabelle erzeugt werden .
  • Es ist möglich, die Daten mit der WHERE Anweisung in SQL zu filtern, das Dataset zu schliessen und wieder zu öffnen (oder die Methode RefetchData aufrufen). Aber in diesem Fall müssen die Reihenfolge und Anzahl der Felder gleich bleiben.
  • Es ist auch möglich, komplexe SQL-Anweisungen zu verwenden mittels Aliasen, Joins, Views bei mehrfachen Tabellen (denken sie daran, dass sie sich in der selben Datendatei befinden müssen), aber in diesem Fall wird ApplyUpdates nicht funktionieren. Wenn jemand komplexe Abfragen benutzen und die Updates in die Datendatei einsetzen will, soll er mir schreiben und ich werde einige Hinweise geben, wie man das tut.
  • Es ist erlaubt, den Dateinamen zu einer sqlite2.x Datendatei zu setzen, welche nicht von TSqliteDataset erzeugt wurde, aber einige Felder werden nicht den korrekten Feldtyp ermitteln. Diese werden als String-Felder behandelt.

Allgemeine Beispiele sind zu finden im fpc/fcl/db/sqlite CVS-Verzeichnis

Luiz Américo pascalive(at)bol(dot)com(dot)br

Lazarus und MSSQL

Bitte schreiben sie mir!

Lazarus und Interbase / Firebird

Schauen Sie auf Installation von Packages nach. Auf dieser Seite befindet sich ein erstes kleines Beispiel und eine Beschreibung, wie man eine Verbindung zu einem IB- oder FB-Server herstellt. Informationen zu Firebird gibt es auch hier Firebird.

Funktioniert auch mit der neuesten Zeoslib (aus dem cvs).

FBLib Firebird-Bibliothek

FBLib ist eine Open-Source-Bibliothek für den direkten Zugriff auf das relationale Datenbanksystem Firebird. Funtioniert mit Borland Delphi, Kylix, Free Pascal und Lazarus.

Folgende Merkmale sind aktuell enthalten:

  • Direkter Zugriff auf Firebird 1.0.x 1.5.x, 2.x Classic oder SuperServer
  • Multi-Plattform [Win32, Gnu/Linux, FreeBSD)
  • Automatische Auswahl der Klientenbibliothek 'fbclient' oder 'gds32'
  • Abfragen mit Parametern
  • Unterstützt den SQL-Dialekt 1/3
  • LGPL Lizenz-Vereinbarung
  • Extrahiert Metadaten
  • Einfacher Skript-Parser
  • Fügt nur 100-150 KB zur ausführbaren EXE-Datei hinzu
  • Unterstützt BLOB-Felder
  • Exportiert Daten zu einem HTML SQL Script
  • Service-Manager (Backup, Restore, gfix...)
  • Ereignis-Benachrichtigung

Sie können die Dokumentation von der FBLib Website herunterladen.

Hiere finden Sie eine aktuelle Version. Oder Sie benutzen SVN: [1] (Tipp von Guionardo)

Lazarus und dBase

Tony Maro

Sie können auch mit dem Besuch der TDbf Tutorial Seite anfangen.

FPC enthält eine einfache Datenbank-Komponente, die ähnlich funktioniert wie die Delphi-Komponente TTable, genannt "TDbf" (TDbf Webseite), die eine sehr elementare Teilmenge von Features für dBase-Dateien bietet. Sie wird inzwischen standardmäßig installiert, so dass sie das Lazarus Package aus dem "lazarus/components/tdbf" Verzeichnis nicht mehr manuell installieren und ihre Lazarus IDE neu aufbauen müssen (rebuild). Sie erscheint neben 'TDatasource' in ihrer Komponentenpalette.

Die Komponente TDbf hat einen Vorteil gegenüber anderen Datenbank-Komponenten, dass sie keine Art von Datenbank-Laufzeit-engines benötigt. Sie ist aber nicht die beste Option für große Datenbankanwendungen.

Sie ist sehr einfach zu benutzen. Nehmen sie einfach eine TDbf und legen sie sie auf ihrem Formular ab, setzen den Laufzeit-Pfad auf das Verzeichnis, wo sich ihre Datenbank-Dateien befinden, setzen den Tabellennamen und verbinden sie mit ihrer TDatasource-Komponente.

Wirkliche Funktionalität benötigt ein bißchen mehr Aufwand, wie auch immer. Wenn eine Tabelle nicht bereits schon existiert, müssen sie sie per Programm erzeugen, es sei denn, es gibt einen kompatiblen Tabellen-Designer, mit dem ich nicht vertraut bin.

Der Versuch, eine nicht existierende Tabelle zu öffnen, wird einen Fehler erzeugen. Tabellen können per Programm durch die Komponente erzeugt werden, sobald der Laufzeit-Pfad und der Tabellenname gesetzt wurden.

Ein Beispiel: Sie erzeugen eine Tabelle mit dem Namen "dvds", um ihre DVD-Kollektion zu speichern, in dem sie sie auf ihrem Formular ablegen, den Laufzeit-Pfad setzen und den Tabellennamen auf "dvds" setzen. Die resultierende Datei heißt "dvds.dbf".

Fügen sie das Folgende in ihren Code ein:

   Dbf1.FilePathFull = '/Pfad/zu/meiner/Datenbank';
   Dbf1.TableName = 'dvds';
   With Dbf1.FieldDefs do begin
       Add('Name', ftString, 80, True);
       Add('Description', ftMemo, 0, False);
       Add('Rating', ftString, 5, False);
   end;
   Dbf1.CreateTable;

Wenn dieser Code läuft, wird ihre Tabelle DVD-Kollektion erzeugt. Danach werden alle datensensitiven Komponenten, die durch TDatasource mit dieser Komponente verbunden sind, einen einfachen Zugang zu den Daten erlauben.

Das Hinzügen von Indexen ist ein wenig unterschiedlich von ihrer typischen TTable. Es muss getan werden, nachdem die Datenbank geöffnet wurde. Es ist auch die selbe Methode, die sie zum Erneuern der Indexe verwenden. Zum Beispiel:

   Dbf1.Exclusive := True;
   Dbf1.Open;
   Dbf1.AddIndex('dvdsname','Name',[ixPrimary, ixUnique, ixCaseInsensitive]);
   Dbf1.AddIndex('rating.ndx', 'Rating', [ixCaseInsensitive]);
   Dbf1.Close;

Der erste (primary) Index ist eine Datei mit dem Namen "dvdsname.mdx" und der zweite ist die Datei "rating.ndx". Daher müssen sie aufpassen in einer Mehrfach-Tabellen Datenbank, den selben Dateinamen nicht zweimal zu verwenden.

Ich will versuchen, ein detaillierteres Beispiel zu einem späteren Zeitpunkt hinzuzufügen, aber hoffentlich wird dies jene 'alten' Delphi-Programmierer anspornen, Datenbankprogramme mit Lazarus zu schreiben!

Verwendung von TSdfDataset und TFixedDataset

TSdfDataset and TFixedDataset are two simple datasets which offer a very simple textual storage format. These datasets are very convenient for small databases, because they are fully implemented as an object pascal unit, and thus require no external libraries, and because their textual format allows them to be easely edited with a text editor.

To start with this formats, a initial database file should be created. The format is very simple, so use a text editor to do this.

Below is a sample database for TSdfDataset. Note that the first line has the names of the fields and that we are using commas as separators:

ID,NAMEEN,NAMEPT,HEIGHT,WIDTH,PINS,DRAWINGCODE
1,resistor,resistor,1,1,1,LINE
2,capacitor,capacitor,1,1,1,LINE
3,transistor npn,transistor npn

And here is an example database for using with TFixedDataset. Each record occupies a fixed amount of space, and if the field is smaller then it, spaces should be used to fill the remaining size.

Name = 15 chars; Surname = 15 chars; Tell = 10 chars; e_mail = 20 chars;
Piet           Pompies                  piet@pompies.net    

Direkte Verwendung der Datasets

Sometimes it is useful to create the dataset and work with it completely in code, and the following code will do exactly this. Note some peculiarities of TSdfDataset/TFixedDataset:

  • The lines in the database can have a maximum size of about 300. A fix is being researched.
  • It is necessary to add the field definitions. Some datasets are able to fill this information alone from the database file
  • One should set FirstLineAsSchema to true, to indicate that the first line includes the field names and positions
  • The Delimiter property holds the separator for the fields. It will not be possible to use this char in strings in the database. Similarly it will not be possible to have lineendings in the database because they mark the change between records. It's possible to overcome this by substituting the needed comma or line ending with another not often used char, like # for example. So that when showing the data on screen all # chars could be converted to line endings and the inverse when storing data back to the database. The ReplaceString routine is useful here.
constructor TComponentsDatabase.Create;
begin
  inherited Create;

  FDataset := TSdfDataset.Create(nil);
  FDataset.FileName := vConfigurations.ComponentsDBFile;

  // Not necessary with TSdfDataset
//  FDataset.TableName := STR_DB_COMPONENTS_TABLE;
//  FDataset.PrimaryKey := STR_DB_COMPONENTS_ID;

  // Adds field definitions
  FDataset.FieldDefs.Add('ID', ftString);
  FDataset.FieldDefs.Add('NAMEEN', ftString);
  FDataset.FieldDefs.Add('NAMEPT', ftString);
  FDataset.FieldDefs.Add('HEIGHT', ftString);
  FDataset.FieldDefs.Add('WIDTH', ftString);
  FDataset.FieldDefs.Add('PINS', ftString);
  FDataset.FieldDefs.Add('DRAWINGCODE', ftString);

  // Necessary for TSdfDataset
  FDataset.Delimiter := ',';
  FDataset.FirstLineAsSchema := True;

  FDataset.Active := True;

  // Sets the initial record
  CurrentRecNo := 1;
  FDataset.First;
end;

When using TSdfDataset directly be careful that althought it is implemented, RecNo does not work correctly, neither for setting nor for reading. The standard movimentation routines like First, Next, Prior and Last work correctly, so it's possible to use them to implement a replacement for RecNo. Keep a variable somewhere called CurrentRecNo which will hold the current RecNo value. Remember that this variable will have the same convention as RecNo, so the first record has number 1. After activating the database initialize the database to the first record with TSdfDataset.First and with CurrentRecNo := 1

{@@
  Moves to the desired record using TDataset.Next and TDataset.Prior
  Avoids using TDataset.RecNo which doesn't work in all datasets

  @param AID Indicates the record number. The first record has number 1
}
procedure TComponentsDatabase.GoToRec(AID: Integer);
begin
  // We are before the desired record, move forward
  if CurrentRecNo < AID then
  begin
    while (not FDataset.EOF) and (CurrentRecNo < AID) do
    begin
      FDataset.Next;
      FDataset.CursorPosChanged;
      Inc(CurrentRecNo);
    end;
  end
  // We are after the desired record, move back
  else if CurrentRecNo > AID  then
  begin
    while (CurrentRecNo >= 1) and (CurrentRecNo > AID) do
    begin
      FDataset.Prior;
      FDataset.CursorPosChanged;
      Dec(CurrentRecNo);
    end;
  end;
end;

Verwendung mit datensensitiven Komponenten

Siehe auch

Externe Links

  • Pascal Data Objects - eine Datenbank API die mit FPC und Delphi funktioniert und die nativen MySQL-Bibliotheken für Version 4.1 und 5.0 sowie Firebird SQL 1.5 und 2.0 verwendet. Sie wurde durch PHP's PDO-Klasse angeregt.
  • Zeos+SQLite Tutorial - Ein gutes Tutorial mit Screenshots. Es erklärt wie Sie SQLite und Zeos benutzen. Allerdings auf Spanisch - (Google translate hilft bei der Übersetzung ins Deutsche)