Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   SQLITE Connection erstellen: Anleitung erbeten (https://www.delphipraxis.net/214905-sqlite-connection-erstellen-anleitung-erbeten.html)

walsch.rene 3. Apr 2024 08:16

Datenbank: SQLITE • Version: 3 • Zugriff über: TFDConnection

SQLITE Connection erstellen: Anleitung erbeten
 
Guten Morgen,

wo finde ich eine ausführliche Schritt-für-Schritt-Anleitung für das Erstellen einer Connection zu einer SQLITE-Datenbank? Im Netz finden sich Anleitungen ohne Zahl, die auch funktionieren, solange man sie Schritt für Schritt abarbeitet. Sobald ich aber eigene Wege gehe, scheitere ich.

Mein Ziel:
Auf Dienstrechnern möchte ich eine SQLITE-Datenbank mit einem Delphi GUI anlegen. Weder ich noch die Kollegen haben Adminrechte und werden sie auch nicht bekommen. Die DB wird auf einem gemeinsamen Netzlaufwerk liegen, das GUI auf jedem Dienstrechner.

Mein Problem:
Obwohl es die SQLITE-DB gibt und sie auch Tabellen enthält und diese auch Daten enthalten (alles mit Visual Studio Code angelegt bzw. eingegeben) und obwohl ich zur Designzeit sowohl die Connection (TFDConnection) als auch die Tabellen (TFDQuery) auf Connected bzw. Active setzen kann, erhalte ich zur Laufzeit die Fehlermeldung "Tabelle tabellenname existiert nicht".
Ich habe mir daraufhin die Embarcadero (CE 10.4) Trainings-DB SQLITE Demo genommen und mir eine der Tabellen via Datenexplorer in mein GUI-Datenmodul gezogen. Dabei wird bekanntlich eine passende FDConnection erzeugt (die Tabelle aus der Beispiel-DB habe ich sofort wieder gelöscht). In dieser Connection habe ich zur Designzeit lediglich den Database-Parameter auf den absoluten Pfad meiner SQLITE-DB geändert und alle meine Datasets mit dieser FDConnection verbunden. Damit konnte ich vollkommen problemlos arbeiten. Nun wollte ich dem GUI eine Möglichkeit hinzufügen, den Pfad zur DB auf dem Dienstrechner selbst zu wählen (TOpenDialog). Den Parameter Database mit dem kompletten absoluten Pfad habe ich gemäß der Anleitung (http://docwiki.embarcadero.com/CodeE....SQLite_Sample) geändert:

Delphi-Quellcode:
with dbMain do begin
  Close;
  // create temporary connection definition
  with Params do begin
    Clear;
    Add('DriverID=SQLite');
    Add('Database=x:\path_to_database\db.sdb');
  end;
  Open;
end;
Jetzt erhalte ich die Meldung, dass meine Tabelle tabellenname nicht existiert, obwohl sie es tut und ich zuvor problemlos mit ihr arbeiten konnte. An der DB selbst und den Datasets in meinem GUI habe ich keine Veränderungen vorgenommen, nur an der Connection.

Mein Verdacht:
Mit Clear löscht man alle Params, fügt aber per Code nur zwei hinzu.

Wo liegt mein Denkfehler, was mache ich falsch?

Vielen Dank und freundliche Grüße,
René

Der schöne Günther 3. Apr 2024 09:00

AW: SQLITE Connection erstellen: Anleitung erbeten
 
Zitat:

Die DB wird auf einem gemeinsamen Netzlaufwerk liegen, das GUI auf jedem Dienstrechner.
Vorab, bevor du weiter Arbeit reinsteckst: Sqlite ist für sowas keine gute Wahl. Im Endeffekt ist das nicht viel besser als Excel-Dateien auf einem 1990er-Netzlaufwerk und alle greifen drauf zu.

Empfohlener Lesestoff: https://www.sqlite.org/useovernet.html
Zusammenfassung:
Zitat:

Choose the technology that is right for you and your customers. If your data lives on a different machine from your application, then you should consider a client/server database. SQLite is designed for situations where the data and application coexist on the same machine. SQLite can still be made to work in many remote database situations, but a client/server solution will usually work better in that scenario.

Tipp: Du bekommst in Sqlite keine Fehlermeldung wenn du als Pfad eine Datei angibst, die nicht existiert. Du startest dann mit einer leeren Datenbank, und das würde auch zu deiner Fehlermeldung passen, dass die Tabelle nicht existiert.

Stelle nochmal wirklich sicher, ob dein "Laufwerk X:" auch wirklich von deinem Programm aus lesbar ist und der Pfad stimmt.


PS:
Zitat:

Auf Dienstrechnern möchte ich eine SQLITE-Datenbank mit einem Delphi GUI anlegen.
und
Zitat:

Ich habe mir daraufhin die Embarcadero (CE 10.4)
passt irgendwie nicht so wirklich zusammen 🤔

haentschman 3. Apr 2024 09:06

AW: SQLITE Connection erstellen: Anleitung erbeten
 
Willkommen hier. :dp:

Mit dem Schnipsel ist nicht klar welche Objekte du "ansprichst". dbMain = Klasse?, Params von welcher Klasse? (ich tippe auf Connection)

PS:
Delphi-Quellcode:
with Params do begin
Vermeide WITH. :warn: Das gibt nur Probleme. Erst Recht mit Verschachtelung. (falscher Scope, Debbuging). Lieber ausschreiben...

PS:
Wenn du Delphi Code mitteilen möchtest, hast du einen Knopf mit Helm im Editor. Dann wird es formatiert...:zwinker:

Zitat:

Die DB wird auf einem gemeinsamen Netzlaufwerk liegen, das GUI auf jedem Dienstrechner.
...stimmt. Keine gute Idee. :roll: Besser ein DB System nehmen was mit Multi-User kann... (Firebird etc.)
Zitat:

Weder ich noch die Kollegen haben Adminrechte und werden sie auch nicht bekommen
...Du mußt doch die Datenbank admistrieren/ändern. :gruebel: Da brauchst du doch Zugriff auf das Laufwerk mit der Datenbank. Willst du jedesmal die Admins belästigen?

walsch.rene 3. Apr 2024 10:54

AW: SQLITE Connection erstellen: Anleitung erbeten
 
Liebe Beide,

vielen Dank für Eure Antworten. Leider werden (wie so oft in Foren) Meinungen kundgetan, um die der Fragende nicht gebeten hat (es gehört auch zur Nettiquette in Foren, ausschließlich auf die Frage zu antworten :wink:)

1) Ich kann die Tatsache nicht ändern, dass in dem Forschungsinstitut, in dem die DB zum Einsatz kommen soll, aus Sicherheitsbedenken keine selbstgeschriebene oder OpenSource-Software installiert wird. SQLITE kann von einem User "verwaltet" werden (z.B. über eine Tabelle User mit Username und Password), ohne dass sie/er Adminrechte auf dem Rechner hat.

2) Ich habe mich im Vorfeld meiner Wahl ausführlich mit der Frage des DB-Systems beschäftigt, von MSAccess über DBase bis MySQL und MariaDB. Nur DBase (nun wirklich veraltet) und SQLITE kommen ohne Adminrechte aus (siehe oben). Die DB muss keine Superkräfte wie Multiuserfähigkeit oder Rollback haben. SQLITE ist unter den gegebenen Umständen für mich die perfekte Wahl.

Sorry, Jungs, ich möchte weder unfreundlich noch undankbar wirken, aber ich bin von den Restriktionen mindestens so frustriert wie Ihr, muss aber mit ihnen leben.

So, nun noch einmal zurück zu meiner Frage: Ich möchte in einer zur Designzeit erstellten und bestens funktionierenden FDConnection (das sollte die Frage nach der Klasse eigentlich schon in meinem initialen Beitrag hinreichend beantwortet haben) nur den absoluten Pfadnamen ändern und sonst nichts. Einen relativen Pfadnamen scheint der SQLITE-Treiber nicht zu unterstützen und ich benötige ihn auch nicht, denn wie gesagt: jeder User soll von seinem GUI auf dieselbe DB irgendwo auf einem Netzlaufwerk zugreifen können, das jede(r) unter einem anderen Laufwerkbuchstaben eingebunden haben dürfte. Muss ich wirklich mit .Params.Clear alle Parameter löschen? Wäre vielleicht ein "Überschreiben" von .Params['Database'] möglich? Liegt mein Problem überhaupt an den Parametern? Immerhin hat Embarcadero den zitierten Code als Beispiel gewählt.

Beste Grüße,
René

Frickler 3. Apr 2024 12:39

AW: SQLITE Connection erstellen: Anleitung erbeten
 
Zitat:

Zitat von walsch.rene (Beitrag 1535257)
Die DB muss keine Superkräfte wie Multiuserfähigkeit [...]

Es greift also immer nur ein Benutzer zur gleichen Zeit auf die Daten zu?

johndoe049 3. Apr 2024 13:17

AW: SQLITE Connection erstellen: Anleitung erbeten
 
Steuerelement auf die GUI ziehen und auswählen. Dann erscheint links der Eigenschaftseditor.

Such dir den Eintrag für den Datenbankpfad und Namen raus.

Vereinfachtes generisches Beispiel:
Code:
datenbankkonnektor.connected := false //erst trennen, dann ändern. kann man aber auch im Eigenschaftseditor direkt als disconnect einstellen
datenbankkonnektor.dateipfad := 'irgendwo, wo gespeichert';
datenbankkonnektor.dateiname := 'irgendwas.sqlite';
datenbankkonnektor.connected := true;
Allgemein gilt, dass man alle Elemente im Elementeditor auch direkt mit dem Konnektornamen ansprechen kann. Funktioniert aber nur. wenn vorher die Datenbank nicht verbunden ist.


Bei Lazarus wäre das z.B.
Code:
SQLite3Connection1.connected := false;
SQLite3Connection1.DatabaseName := 'f:\irgendwohin\NochEineDatenbank.sqlite';
SQLite3Connection1.connected := true;

Delphi.Narium 3. Apr 2024 13:22

AW: SQLITE Connection erstellen: Anleitung erbeten
 
Um herauszubekommen, ob das Problem bei der DB oder der Tabelle liegt, hab' ich mal den Quelltext ein bisserl verändert:
Delphi-Quellcode:
var
  sDBFile : String;
begin
  sDBFile := 'x:\path_to_database\db.sdb';
  if FileExists(sDBFile) then begin
    dbMain.Close;
    // create temporary connection definition
    dbMain.Params.Clear;
    dbMain.Params.Add('DriverID=SQLite');
    dbMain.Params.Add(Format('Database=%s',[sDBFile]));
    dbMain.Open;
  end else begin
    MessageDlg('Datenbankdatei wurde nicht gefunden' + sLineBreak + sDBFile,mtError,[mbOk],0);
  end;
end;
So erfährst Du, ob die Datenbank überhaupt vorhanden / im Zugriff ist. Eventuell fehlt ja nicht die bemängelte Tabelle, sondern aus irgendwelchen Gründen (Zugriffsrechte auf x:\, den Pfad, ... fehlen) kann auf die Datenbankdatei nicht zugegriffen werden.

walsch.rene 3. Apr 2024 15:47

AW: SQLITE Connection erstellen: Anleitung erbeten GELÖST!
 
Liebe Alle,

Erstens: Man kann den Parameter einfach überschreiben, auch wenn in der zur Designzeit angelegten Connection bereits eine andere DB steht. Params.Clear ist nicht notwendig.
Delphi-Quellcode:
procedure TFormMain.OpenDB(ADBFile: string);
begin
  with MyConnection do
  begin
    Close;
    with Params do
    begin
      Add('Database= ' + ADBFile);
    end;
    Open;
  end;
  dm.Table1.Open;
  dm.Table2.Open;
  // usw.
end;
Zweitens: Der Grund meines ständigen Scheiterns war ein anderer. Wenn man eine TFDConnection (SQLITE) zur Designzeit Connected := True setzt und die im Parameter 'Database' definierte SQLite-DB nicht vorhanden ist, wird sie automatisch angelegt! Bei anderen Datenbanksystemen würde es bei fehlendem DB-File nicht möglich sein, das Kästchen im Objektinspektor zu aktivieren, bei SQLITE schon. Das Programm macht ahnungslos weiter mit dem Öffnen der Tables (TFDQuery), weil es die DB "gefunden" zu haben glaubt, aber natürlich findet es nun die Tabellen nicht. Daher die ständigen Fehlermeldungen: [FireDAC][Phys][SQLite] ERROR no such table.

Ganz herzlichen Dank!

Beste Grüße,
René

walsch.rene 3. Apr 2024 15:54

AW: SQLITE Connection erstellen: Anleitung erbeten
 
O Mann, gerade lese ich, dass Der schöne Günther mich schon auf das Problem hingewiesen hatte! Wer lesen kann, ist klar im Vorteil!
Zitat:

Tipp: Du bekommst in Sqlite keine Fehlermeldung wenn du als Pfad eine Datei angibst, die nicht existiert. Du startest dann mit einer leeren Datenbank, und das würde auch zu deiner Fehlermeldung passen, dass die Tabelle nicht existiert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:59 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz