Datenbanken in Lazarus

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
Bora4d
Beiträge: 290
Registriert: Mo 24. Dez 2007, 13:14
OS, Lazarus, FPC: WinXP-Pro-Sp3, Xubuntu 12.04, (Laz 1.1-SVN Mai2012, FPC 2.6.1 / 2.6.0-Linux)
CPU-Target: AMD64X2

Re: Datenbanken in Lazarus

Beitrag von Bora4d »

MmVisual hat geschrieben:Wegen meinem Problem, ich habe ZEOS V6.6Stable. Vieleicht ist ja das das Problem? Denn mit der V6.6 kann nur bis zur FB Version 2.1 auswählen. Ich werden mal FB2.1 installieren und dann das ganze nochmals versuchen. Mein Lazarus kommt vom 23.08.10.
Kann man in der ZEOS V7.0 FB2.5 auswählen?

Nein, auch mit ZOS 7 nur bis FB 2.1. Aber es hat troztem funktioniert weil es ja die db nicht selber bearbeatet sondern über fbclient.dll an fb weiterleitet.
Ich habe an dein Code nichts geändert nur zum Schluß die Grid hinzugefügt um Ergebnis anzuschauen. Bei ZConnection.Protocol ist immer noch "firebird-2.1" ausgewählt.
Ich habe 2.5 nur installiert weil meine FB-Server deine DB nicht lesen konnte. Ich habe dein Program mit FB2.5 getesttet und verstehe deshalb nicht warum du 2.1 installieren willst.
Noch eins, du solltest falls du windows verwendest fbclient.dll von fb-ordner ins windows\system32 ordner kopieren.
Und starte dein Program mit der Konsole (cmd.exe/Eingabeaufforderung) vielleicht bekommst du mehr Fehlermeldungen als SIGSAV...

Hercules:
Gutes gelingen.

MmVisual
Beiträge: 1466
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Datenbanken in Lazarus

Beitrag von MmVisual »

Es liegt an der ZEOS V6.6. Die ist doch nichst so "Stable".

Ich hab jetzt mal das Lazarus-Paket von heute geladen und ZeosV7 installiert, siehe da es geht nun bei mir auch.
@Bora4d vielen Dank für den Test!

Weiß jemand warum die Zeos V7 immer noch im Alpha Stadium ist?
Das ist sie ja schon seit fast 2 Jahren. Oder hält der Entwickler Winterschlaf?

Grüße Markus.
EleLa - Elektronik Lagerverwaltung - www.elela.de

MmVisual
Beiträge: 1466
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Datenbanken in Lazarus

Beitrag von MmVisual »

Ich habe jetzt in meiner Mamut-Applikation die Firebird-Datenbank aktiviert bekommen und bin gerade dabei Daten zu füllen.

Bei den Blob-Feldern habe ich nun ein Problem. Ich bekommen kein Bild in die Datenbank.

Das Bild mache ich ein einen Stream, wenn der kleiner als 64KB ist, dann wird der erlaubt in die Datenbank zu schreiben, ansonsten Fehlermeldung.

Das Schrieben geht so:
qFotoBild: TBlobField;
qFotoBild.LoadFromStream(st); // Feld

Bei Post gibt es dann die Fehlermeldung:
SQL Error: Malformed string. Error Code: -104. Invalid token The SQL: INSERT INTO FOTO (ID,BEZEICHNUNG,TABELLE,BILDTYP,BILD,AENDDATUM) VALUES (?,?,?,?,?,?);

Die Tabelle wurde mit diesem SQL-Befehl angelegt:

Code: Alles auswählen

CREATE TABLE FOTO (
  ID INTEGER NOT NULL,
  BEZEICHNUNG VARCHAR(80) CHARACTER SET UTF8 DEFAULT NULL,
  TABELLE VARCHAR(30) CHARACTER SET UTF8 DEFAULT NULL,
  BILDTYP VARCHAR(10) CHARACTER SET UTF8 NOT NULL,
  BILD BLOB SUB_TYPE 1 SEGMENT SIZE 80,
  AENDDATUM TIMESTAMP DEFAULT 'NOW',
  CONSTRAINT FOTO_ID_PX PRIMARY KEY (ID)
);


Eigentlich wollte ich den BLOB SUB_TYPE 2 nehmen, wird aber von Firebird nicht unterstützt. (Bei MySQL / SQLite kann ich problemlos Bilder speichern)

Hat jemand eine Idee, was ich ändern könnte damit es klappt?

Vielen Dank im Voraus. Gruß Markus
EleLa - Elektronik Lagerverwaltung - www.elela.de

MmVisual
Beiträge: 1466
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Datenbanken in Lazarus

Beitrag von MmVisual »

OK, ich habs raus gefunden, SUB_TYPE muss 0 sein.
EleLa - Elektronik Lagerverwaltung - www.elela.de

MmVisual
Beiträge: 1466
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Datenbanken in Lazarus

Beitrag von MmVisual »

Ich habe jetzt all meine Daten importiert in Firebird. Anbei ein Testbericht.

Firebird ist mindestens 5x langsamer als MySQL. SQLite ist nochmals schneller.

Am besten ist es die EXE so zu gestalten dass die Daten mit SQLite und MySQL verwaltet werden können. Der Hauptunterschied ist, dass in SQLite/MySQL der Quote-Char ein ` ist und in Firebird ein ".

Zeiten:
- Firebird: 1,61 s
- MySQL: 0,31 s
- SQLite: 0,16 s

Test:
- Gleiche EXE
- Gleiche Datenmenge
- ca. 1600 Datensätze
- Als LIKE steht ein % drin (alles finden)

Das ist der Code:

Code: Alles auswählen

qSuch.SQL.Text := 'SELECT b.ID, l.ID AS LID, b.tree_typ_ID, b.Bezeichnung AS Bezeichnung,';
  qSuch.SQL.Add('l.Bezeichnung AS LBez, g.Bezeichnung AS CBez, l.SMD, l.SMD_Text,');
  qSuch.SQL.Add('k.Bezeichnung AS KBez, l.LagerNr, l.Menge, l.Haltbar, l.Barcode, adr.Bezeichnung AS AdrBez,');
  qSuch.SQL.Add('a.BestellNr, a.EPreis, (a.EPreis * l.Menge) AS GPreis');
  qSuch.SQL.Add('FROM bauteil b');
  qSuch.SQL.Add('LEFT JOIN bauteillager l ON (b.ID = l.Bauteil_ID)');
  qSuch.SQL.Add('LEFT JOIN bauteiladr a ON (l.ID = a.BauteilLager_ID)');
  qSuch.SQL.Add('LEFT JOIN ' + AnsiQuotedStr('case', cSQLQuote) + ' g ON (g.ID = l.Case_ID)');
  qSuch.SQL.Add('LEFT JOIN kiste k ON (k.ID = l.Kiste_ID)');
  qSuch.SQL.Add('LEFT JOIN adr ON (adr.ID = a.Adr_ID)');
  qSuch.SQL.Add('WHERE b.Bezeichnung LIKE ''' + s + '''');
  qSuch.SQL.Add('OR l.Bezeichnung LIKE ''' + s + '''');
  qSuch.SQL.Add('OR l.SMD_Text LIKE ''' + s + '''');
  qSuch.SQL.Add('OR l.LagerNr LIKE ''' + s + '''');
  qSuch.SQL.Add('OR l.Barcode LIKE ''' + s + '''');
  qSuch.SQL.Add('OR a.BestellNr LIKE ''' + s + '''');
  qSuch.SQL.Add('ORDER BY Bezeichnung');


Weil Interbase mir irgend wann einmal zu langsam wurde (über 10000 Datensätze, Indexierung gesetzt usw.) habe ich MySQL verwendet.

Größe Datenbank:
- Firebird: 6,8MB
- SQLite: 4,6MB
- MySQL: 8,3MB
EleLa - Elektronik Lagerverwaltung - www.elela.de

Kiffi
Beiträge: 37
Registriert: Sa 27. Mär 2010, 11:39
OS, Lazarus, FPC: Windows 7 / Lazarus 1.0
CPU-Target: 32/64 bit

Re: Datenbanken in Lazarus

Beitrag von Kiffi »

@MmVisual: hast Du schon mal probiert, Deine Abfrage in
eine Stored Procedure zu verlagern? AFAIK dürfte das doch
die Geschwindigkeit verbessern.

Grüße ... Kiffi

Bora4d
Beiträge: 290
Registriert: Mo 24. Dez 2007, 13:14
OS, Lazarus, FPC: WinXP-Pro-Sp3, Xubuntu 12.04, (Laz 1.1-SVN Mai2012, FPC 2.6.1 / 2.6.0-Linux)
CPU-Target: AMD64X2

Re: Datenbanken in Lazarus

Beitrag von Bora4d »

Ich habe mal sqlite3 mit fb15 verglichen. Damals war FB schneller außer bei einfachen "select * from xy". Und von FB hatte ich embedded Version benutzt.
Ich denke Sqlite mit Serverversion von FB zu vergleichen ist falsch weil bei FB alles über HTTP protocol läuft. Wenn man 4-5 Tabellen verkettet dann war bei sqlite extrem langsam.
Ich habe damals hier berichtet:
viewtopic.php?f=17&t=1232&p=15948#p15948

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6208
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Datenbanken in Lazarus

Beitrag von af0815 »

HMMM - mit Tests bin ich vorsichtig. Wie weit ist der Test für die geplante Applikation aussagekräftig ? Weiters reagiert ein jedes Datenbanksystem etwas anders und hat Schwächen und Stärken. Es kommt bei so schnellschußtest ein reines 'Schwanzlängenresultat' heraus. Jeder hat halt den länsten. Das Resultat selbst ist aber nicht wirklich brauchbar.

Wenn meine DB nur so groß ist, das sie in den Speicher passt bei zB. 16000 Datensätze, dann wird fast jedes System das die Daten im Speicher hält die Nase vorne haben. Ev. sind da reine Records am schnellsten.

Wenn es komplexere Abfragen sind, so hägt es vom Design ab wie schnell die DB wird. Das Zusammenspiel der Abfrageoptimierer, Abfragedesign, Indizes, ... kann da Abfragen auf 5 min bringen oder auf 5 sec.

Ich habe mich damit fast 5 jahre herumgeschlagen, das Thema hat mir viele graue Haare gebracht. Da machst du eine vermeintlich gute Abfrage, siehst dir die Ausführungspläne und Geschwindigkeit an und kommst drauf, das der Server abolut nichts davon hält :-) Aber das ist eine andere (unendliche) Geschichte.

@MmVisual
Bei der DB, wenn sie nicht dramatisch größer wird, würde ich sicherlich mal SQLLite oder sogar eine Struktur im Speicher verwenden. Was ein Kriterium sein könnte, ist die MultiUsertauglichkeit. Dann würde ich zum Firebird tendieren, der ist da IMHO da am Ausgereiftersten.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

MmVisual
Beiträge: 1466
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Datenbanken in Lazarus

Beitrag von MmVisual »

So, nun habe ich Indize gesetzt, siehe da, die Abfrage braucht jetzt nur noch 0,36s.

Code: Alles auswählen

CREATE INDEX BAUTEILLAGER_BAUTEIL_ID_IX ON BAUTEILLAGER (BAUTEIL_ID);
CREATE INDEX BAUTEILADR_BAUTEIL_ID_IX ON BAUTEILADR (BAUTEIL_ID);
CREATE INDEX BAUTEILLAGER_CASE_ID_IX ON BAUTEILLAGER (CASE_ID);
CREATE INDEX BAUTEILLAGER_KISTE_ID_IX ON BAUTEILLAGER (KISTE_ID);
CREATE INDEX BAUTEILADR_ADR_ID_IX ON BAUTEILADR (ADR_ID);
CREATE INDEX BAUTEIL_BEZ_IX ON BAUTEIL (BEZEICHNUNG);
CREATE INDEX BAUTEILLAGER_BEZ_IX ON BAUTEILLAGER (BEZEICHNUNG);
CREATE INDEX BAUTEILLAGER_SMD_Text_IX ON BAUTEILLAGER (SMD_TEXT);
CREATE INDEX BAUTEILLAGER_LAGERNR_IX ON BAUTEILLAGER (LAGERNR);
CREATE INDEX BAUTEILLAGER_BARCODE_IX ON BAUTEILLAGER (BARCODE);
CREATE INDEX BAUTEILADR_BESTELLNR_IX ON BAUTEILADR (BESTELLNR);


Eine Stored Procedure will ich nicht in die DB machen, da die EXE mit möglichst vielen Datenbanken und möglichst wenig Sonderschalter laufen soll.

Edit:
Ich will ja auch Fair sein. In MySQL habe ich die Indize nun auch nachgeführt und der braucht jetzt nur noch 0,13s für die Abfrage.
SQLite mit den Indize 0,14s

Jeder sollte am besten mal selbst seine Daten mit mehreren Datenbanken testen. Zeos unterstützt einen dabei dank der "Protocol" Eigenschaft. Wenn man so programmiert dass man mehrere DB's nutzen kann ist man schlussendlich flexibler.
SQLite - Für Einzelplatzsysteme, Lokal, USB-Stick Tauglich, grauselig im DB-Design bei Neuentwicklung (kein Drop Field, uvm.)
Firebird - Free for Use
MySQL - geht auch über Provider / Internet-Datenbank
MSSQL - Na wenns den Microsoft sein muss :-/
Oracle - Die ganz großen Firmen
Zuletzt geändert von MmVisual am Sa 23. Okt 2010, 20:47, insgesamt 1-mal geändert.
EleLa - Elektronik Lagerverwaltung - www.elela.de

baba
Beiträge: 265
Registriert: Mi 4. Apr 2007, 17:47

Re: Datenbanken in Lazarus

Beitrag von baba »

Moin, moin,

versuche mal Postgres, es sollte um einiges schneller als MySQL sein und ist zudem SQL konform, also kein eigener Syntax. Ich benötige für die Abfrage von 5 Sätzen mit jeweils 62 Feldern, aus ca. 60000 Einträgen ohne jeden Index ca. 0,2 Sek. Der Postgres-Server ist ein MacMini, 2.2 GHz., 1 GB RAM, also nichts besonderes.

Baba.

MmVisual
Beiträge: 1466
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Datenbanken in Lazarus

Beitrag von MmVisual »

OK, Postgres V9 habe ich gerade installiert und geladen.

Mit ZEOS kann ich aber nur V8 auswählen. Ich ignoriere das mal.

Ich habe nun meine Tabellen angelegt, z.B.:

Code: Alles auswählen

CREATE SEQUENCE PARAM_ID_SEQ;
CREATE TABLE PARAM (
  ID INTEGER NOT NULL DEFAULT NEXTVAL('PARAM_ID_SEQ'),
  PARNR INTEGER,
  PARNAME VARCHAR(40),
  LAND VARCHAR(5),
  VALINT INTEGER,
  VALFLOAT DOUBLE PRECISION,
  VALTEXT VARCHAR(250),
  AENDDATUM TIMESTAMP NOT NULL DEFAULT 'NOW',
  CONSTRAINT PARAM_ID_PX PRIMARY KEY (ID)
);
ALTER SEQUENCE PARAM_ID_SEQ OWNED BY PARAM.ID;


Nun möchte ich die Daten füllen und es erscheint bei:
Query.Append;
Query.Fields[0].AsInteger = 1; // <<< Hier Exception (Feld: ID)
der Fehler:
Invalid argument index in format ""

Weiß jemand auch hier Rat, warum ich in die Query mit dem ID Feld nichts rein schreiben kann?
ZEOS 7.0

Andere Daten kann ich eingeben, sogar Bilder speichern klappt auf Anhieb.

Gruß Markus.

PS: Nach der Installation von Postgres fehlte dem Zeos die DLL, ist ja klar. Aber nachdem ich die einkopiert habe fehlten noch mehr DLLs, damit es ging musste ich extra die PATH Variable mit dem BIN Verzeichnis von Postgres erweitern.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6208
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Datenbanken in Lazarus

Beitrag von af0815 »

Bei Feldern die einen 'autoincrement' haben, würde sonst der Wert zerstört werden. Also entweder ohne autoincrements arbeiten oder nicht darauf zugreifen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

MmVisual
Beiträge: 1466
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Datenbanken in Lazarus

Beitrag von MmVisual »

Die Antwort ist leider nicht ganz richtig.

Ich habe eine Sicherung der Datenbank, nun will ich diese einspielen.
In der Datenbank gibt es Datenzeilen mit der ID 1, 5, 6, 8 also mit Lücken da vor der Sicherung auch mal was gelöscht wurde.
Damit die ID-Verweise passen, müssen die Daten genau so wiederhergestellt werden, also mit den Lücken bei den ID's, denn sonst passen die ID-Verweise anderen Tabellen nicht mehr.

Das muss doch möglich sein. Oder wie programmiert Ihr eine Datensicherung/Restore in eure Applikation?

Grüße Markus.

Edit:
Ich habe jetzt Postgrees 9.0 deinstalliert und 8.4 installiert. Aber das gleiche.
Nach dem Öffnen wird irgendwie die ReadOnly - Eigenschaft des Feldes ID auf TRUE gesetzt. Wenn ich die auf FALSE setzte, dann kann ich darauf schrieben. Wenn jedoch ein Post auf den Datensatz ausgeführt wird, dann kommt die Meldung:
"Cannot update this query type"
EleLa - Elektronik Lagerverwaltung - www.elela.de

baba
Beiträge: 265
Registriert: Mi 4. Apr 2007, 17:47

Re: Datenbanken in Lazarus

Beitrag von baba »

Lege dein Feld als einfaches INTEGER Feld an, dann kannst du schreiben, musst dich aber selbst um die Verwaltung/Incrementierung kümmern. Durch ein JOIN verknüpfst du die anderen Datenbanken.

Baba.

MmVisual
Beiträge: 1466
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Datenbanken in Lazarus

Beitrag von MmVisual »

In meiner EXE möchte ich mich nicht um das AutoIncrement kümmern.

Es müsste doch ein Schalter geben, den man mit SET setzt, so dass man da einen Wert Reinschreiben kann. Unter MySQL gibt es auch was:
SET FOREIGN_KEY_CHECKS=0;
Um die Daten nacheinander einkopieren zu können.
Dann müsste es einen Befehl geben, mit dem man die Sequenz auf einen bestimmten Wert setzt.

Kann ich ein Trigger machen, ähnlich wie bei Firebird?
Ich habe mit Postgres bisher nie gearbeitet.

Gruß Markus
EleLa - Elektronik Lagerverwaltung - www.elela.de

Antworten