Allgemeines zum Umgang mit Datenbanken
-
- Beiträge: 318
- Registriert: Di 17. Feb 2009, 10:44
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Allgemeines zum Umgang mit Datenbanken
Hallo Zusammen,
ich habe zwei drei allgemeine Fragen zum Umgang mit Datenbanken-hier Firebird 3, auch auf Mac.
Nutzt man für eine DB-Anwendung mehrere TSQLQuery und TDatasource oder nimmt man nur eine und konfiguriert die immer wieder neu, je nachem was man machen will?
Wie bekomme ich einen Löschbefehl an eine query übergeben. Eigentlich primitiv, ich bekomme es nicht hin:
DBeaver akzeptiert DELETE FROM HTBL_FZGE_BEMERK WHERE VERSTEIG_NR = '1' AND DATUM_ID = '1' AND BEMERKUNG_ID = '13';
Der an query.SQL.Text:= SQL-String; übergebene SQL-String passt schon.
Ich muß dazu sagen, dass die Tabelle keinen Primaärschlüssel hat und ich deshalb auch query.UpdateMode:= upWhereAll; gesetzt habe.
Es kommen andauernd Meldungen, dass ein non-select-statement nicht ausgeführt werden könne, oder ein Token -DELETE falsch sei, es an einem Aktiven Query nicht geht, setze ich query.Active:=False kommt die Meldung dass es am inaktiven query nicht geht...
Irgendwie bin ich zu blöd an die query den SQl-String zu übergeben, sodass damit gearbeitet werden kann. Kann mir hier jemand zwei/drei Zeilen Quellcode spendieren?
Dann würde ich gerne in einem Formular ein DBEdit so formatieren, dass die Zahl mit "." als Tausender-Trenner und "€" angezeigt wird. Mit EditMask habe ich es probiert, es will mir nicht gelingen.
Dann habe ich was im Netz gefunden und in der zugehörigen query mit Felder bearbeiten diese hinzugefügt und beim Geldbetrag Currency auf True gesetzt. Die ANzeige funktioniert auch, nur wenn ich den Zahlenwert ändere und über den DBNavigator abschicke kommt die Meldung: "No Update query specified an failed to generate one". Ich hab' doch nur die Felder hinzugefügt die sowieso angezeigt werden und eingestellt, dass das Feld des Geldbetrages halt Currency sein soll ???
Dann noch zu einem Problem beim Mac. Zur Laufzeit werden die DLL hier dylib von Firebird nicht gefunden oder es gibt keinen Zugriff. Wäherend des Designs schon. Das hab' ich entsprechend hinbekommen einzustellen bzw. mit dem LibraryLoader die notwendige *.dylib geladen.
Über den Dateimanager habe ich die Rechte auf den Ordner mit der Datenbank angepasst, den Ordner mit den dylibs, die Rechte auf die Datenbank sowie die Rechte auf die dylibs. Während der Entwicklung, sprich wenn ich an einer query einen "select * from Tabelle" absetzte (den grünen Pfeil drücke) dann wird auch ein Ergebnis angezeigt, nur das Programm will nicht laufen.
Vielen Dank für Hilfe
Viele Grüße
Volker
ich habe zwei drei allgemeine Fragen zum Umgang mit Datenbanken-hier Firebird 3, auch auf Mac.
Nutzt man für eine DB-Anwendung mehrere TSQLQuery und TDatasource oder nimmt man nur eine und konfiguriert die immer wieder neu, je nachem was man machen will?
Wie bekomme ich einen Löschbefehl an eine query übergeben. Eigentlich primitiv, ich bekomme es nicht hin:
DBeaver akzeptiert DELETE FROM HTBL_FZGE_BEMERK WHERE VERSTEIG_NR = '1' AND DATUM_ID = '1' AND BEMERKUNG_ID = '13';
Der an query.SQL.Text:= SQL-String; übergebene SQL-String passt schon.
Ich muß dazu sagen, dass die Tabelle keinen Primaärschlüssel hat und ich deshalb auch query.UpdateMode:= upWhereAll; gesetzt habe.
Es kommen andauernd Meldungen, dass ein non-select-statement nicht ausgeführt werden könne, oder ein Token -DELETE falsch sei, es an einem Aktiven Query nicht geht, setze ich query.Active:=False kommt die Meldung dass es am inaktiven query nicht geht...
Irgendwie bin ich zu blöd an die query den SQl-String zu übergeben, sodass damit gearbeitet werden kann. Kann mir hier jemand zwei/drei Zeilen Quellcode spendieren?
Dann würde ich gerne in einem Formular ein DBEdit so formatieren, dass die Zahl mit "." als Tausender-Trenner und "€" angezeigt wird. Mit EditMask habe ich es probiert, es will mir nicht gelingen.
Dann habe ich was im Netz gefunden und in der zugehörigen query mit Felder bearbeiten diese hinzugefügt und beim Geldbetrag Currency auf True gesetzt. Die ANzeige funktioniert auch, nur wenn ich den Zahlenwert ändere und über den DBNavigator abschicke kommt die Meldung: "No Update query specified an failed to generate one". Ich hab' doch nur die Felder hinzugefügt die sowieso angezeigt werden und eingestellt, dass das Feld des Geldbetrages halt Currency sein soll ???
Dann noch zu einem Problem beim Mac. Zur Laufzeit werden die DLL hier dylib von Firebird nicht gefunden oder es gibt keinen Zugriff. Wäherend des Designs schon. Das hab' ich entsprechend hinbekommen einzustellen bzw. mit dem LibraryLoader die notwendige *.dylib geladen.
Über den Dateimanager habe ich die Rechte auf den Ordner mit der Datenbank angepasst, den Ordner mit den dylibs, die Rechte auf die Datenbank sowie die Rechte auf die dylibs. Während der Entwicklung, sprich wenn ich an einer query einen "select * from Tabelle" absetzte (den grünen Pfeil drücke) dann wird auch ein Ergebnis angezeigt, nur das Programm will nicht laufen.
Vielen Dank für Hilfe
Viele Grüße
Volker
- af0815
- Lazarusforum e. V.
- Beiträge: 6117
- 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: Allgemeines zum Umgang mit Datenbanken
Grundlegend ist es so, das du eine Query mit einem Löschbefehl per Q.Execute aufrufen musst, da keine Datasets zurückgegeben werden.
Generell ist es so, das du eine Query die Eigenschaften
SQL: Für das select
InsertSQL: Wie ein Insert gemacht werden soll
DeleteSQL: Wie wird was aus der DB gelöscht
RefreshSQL: Wie werden die Daten erneuert
UpdateSQL: WIe werden die Daten geändert
Normalerweise schreibst du was bei SQL rein und verlässt dich darauf das die anderen SQL's vom System richtig erraten werden. Das geht bei einfachen Selects wo die Tabellen einen PK haben recht gut und zuverlässig. Nur wenn du keine PK hast, Joins oder nicht editierbare/parametrisierte Sichten verwendest, dann kann die Automatik nichts machen und du musst ran und die entsprechenden Queries ausfüllen (mit den richtigen Parametern).
Zu den anderen Sachen kann ich nichts sagen, da ich eine Allergie auf angebissenes Obst habe.
Generell ist es so, das du eine Query die Eigenschaften
SQL: Für das select
InsertSQL: Wie ein Insert gemacht werden soll
DeleteSQL: Wie wird was aus der DB gelöscht
RefreshSQL: Wie werden die Daten erneuert
UpdateSQL: WIe werden die Daten geändert
Normalerweise schreibst du was bei SQL rein und verlässt dich darauf das die anderen SQL's vom System richtig erraten werden. Das geht bei einfachen Selects wo die Tabellen einen PK haben recht gut und zuverlässig. Nur wenn du keine PK hast, Joins oder nicht editierbare/parametrisierte Sichten verwendest, dann kann die Automatik nichts machen und du musst ran und die entsprechenden Queries ausfüllen (mit den richtigen Parametern).
Zu den anderen Sachen kann ich nichts sagen, da ich eine Allergie auf angebissenes Obst habe.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
Re: Allgemeines zum Umgang mit Datenbanken
Wie greifst du den auf die DB zu? Mit Data Crontrol und Data Access oder?
Zum lernen aber erstmal einen verwenden, sonst wirds zu kompliziert.
In der Regel muss der Query Active True sein, damit es klappt. Während der Entwicklung kannst du ihn aber auf False lasse, da er deinen Code sonst direkt umsetzt, während du noch am tüfteln bist. Du musst nur sicherstellen, dass nach Programmstart Active True wird z.B. in OnShow.
Kommt auf den Anwendungsfall an. Du kannst mit mehreren Querys arbeiten. Manchmal ist das auch notwendig. Du selbst darfst halt nicht den Überblick verlieren und musst im Auge haben, welcher Query gerade was macht.Nutzt man für eine DB-Anwendung mehrere TSQLQuery und TDatasource oder nimmt man nur eine und konfiguriert die immer wieder neu, je nachem was man machen will?
Zum lernen aber erstmal einen verwenden, sonst wirds zu kompliziert.
In der Regel muss der Query Active True sein, damit es klappt. Während der Entwicklung kannst du ihn aber auf False lasse, da er deinen Code sonst direkt umsetzt, während du noch am tüfteln bist. Du musst nur sicherstellen, dass nach Programmstart Active True wird z.B. in OnShow.
- af0815
- Lazarusforum e. V.
- Beiträge: 6117
- 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: Allgemeines zum Umgang mit Datenbanken
Generell halte ich es so, eine Connection und Transaction zur DB. Queries können es beliebig viele sein, ALLERDINGS nur die offen halten die man gerade braucht. Und vor allen selbst aktivieren und selbst wieder schliessen.
Oft benutze ich dynamisch erstellte Queries, ausser ich have fixe Formulare wo das Sinn macht.Für Daten die ich nur kurz Anzeige aber nicht bearbeite, ist es oft besser mit dynamischen Queries zu arbeiten, da man mit diesen Formularen oft Vererbung betreiben kann und ich somit ein Formular habe, es aber öfters verwende. Ich baue geben dann extern das SQL-Statement an das Formular und nehme die Namen aus dem Resultset (Fieldname) und den Datentyp und baue die Anzeige dynamisch auf. Spart bei manchen Applikationen viel und ist für ähnliche Produkte schnell skalierbar.
Grundlegend kannst du ein wenig in den mittlerweile etwas älteren Lazinfos da ein bischen was zu DBs nachlesen.
Oft benutze ich dynamisch erstellte Queries, ausser ich have fixe Formulare wo das Sinn macht.Für Daten die ich nur kurz Anzeige aber nicht bearbeite, ist es oft besser mit dynamischen Queries zu arbeiten, da man mit diesen Formularen oft Vererbung betreiben kann und ich somit ein Formular habe, es aber öfters verwende. Ich baue geben dann extern das SQL-Statement an das Formular und nehme die Namen aus dem Resultset (Fieldname) und den Datentyp und baue die Anzeige dynamisch auf. Spart bei manchen Applikationen viel und ist für ähnliche Produkte schnell skalierbar.
Grundlegend kannst du ein wenig in den mittlerweile etwas älteren Lazinfos da ein bischen was zu DBs nachlesen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 318
- Registriert: Di 17. Feb 2009, 10:44
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Re: Allgemeines zum Umgang mit Datenbanken
Heute ist mir mit meinem Projekt was komisches passiert.
Ich habe das Projekt auf einen anderen Win10 Rechner kopiert und mit der dortigen Lazarus-IDE Compiliert. O.K. beim ersten Versuch kam raus, dass ich Firebird noch als 32 bit installiert hatte. Also deinstalliert und 64 bit heruntergeladen und installiert.
Projekt Compiliert ausgeführt und Kawumm...
Als ich über den Haken des DBNavigator ein Update an einem Feld abschicken wollte kam die Meldung dass es an einer aktiven Datenbank nicht möglich sein. Dabei ging es sich um zwei "Refresh" an einem query und einem "Refresh" eines Dataset des DBGrid.
Ich habe an dem Projekt nix geändert, außer dem Pfad zur Datenbankdatei. Das ist mir ein Rätsel...
Hat ggf. jemand eine Erklärung?
Danke
Volker
Ich habe das Projekt auf einen anderen Win10 Rechner kopiert und mit der dortigen Lazarus-IDE Compiliert. O.K. beim ersten Versuch kam raus, dass ich Firebird noch als 32 bit installiert hatte. Also deinstalliert und 64 bit heruntergeladen und installiert.
Projekt Compiliert ausgeführt und Kawumm...
Als ich über den Haken des DBNavigator ein Update an einem Feld abschicken wollte kam die Meldung dass es an einer aktiven Datenbank nicht möglich sein. Dabei ging es sich um zwei "Refresh" an einem query und einem "Refresh" eines Dataset des DBGrid.
Ich habe an dem Projekt nix geändert, außer dem Pfad zur Datenbankdatei. Das ist mir ein Rätsel...
Hat ggf. jemand eine Erklärung?
Danke
Volker
- af0815
- Lazarusforum e. V.
- Beiträge: 6117
- 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: Allgemeines zum Umgang mit Datenbanken
Wenn das ganze über eine Desktopdatenbank passiert (NICHT SERVER) so kann es sein, das die Db ganz einfach nicht in einem konsitenten Zustand ist. Sprich es hängt zum Beispiel ein abgebrochener Edit Zustand in der DB herum.
Liegt die DB Lokal oder wird auf einen Server im Netzwerk zugegriffen ?
Wenn Desktopdatenbank, wurde die DB in einem konsistenten Zustand kopiert ?
Liegt die DB Lokal oder wird auf einen Server im Netzwerk zugegriffen ?
Wenn Desktopdatenbank, wurde die DB in einem konsistenten Zustand kopiert ?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 318
- Registriert: Di 17. Feb 2009, 10:44
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Re: Allgemeines zum Umgang mit Datenbanken
Die Datenbank liegt lokal in einem Ordner meines Laptop.
Wie kann ich denn prüfen ob die Firebird-DB sich in einem konsistenten Zustand befindet?
Das ist nämlich auch eine Frage die ich mir gestellt habe: Wenn man eine DB, so wie bei Firebird oder SQLite als Datei vorliegen hat, kann man dann zum Sichern der Daten einfach die komplette Datenbankdatei kopieren oder sollten vorher Backuptools Verwendung finden?
Wenn das Projekt fertig ist soll es in einem Netzwerk laufen, wo ich auf einem der Computer Firebird als Superserver installieren wollte.
Dazu hab ich auch noch eine Frage:
Ein Rechner erhält die Serverinstallation. Die anderen teilnehmenden Computer erhalten Client-DLL's richtig? Die liegen dann im selben Ordner wie auch das Lazarus-Programm? Müssen die installiert werden oder werden sie vom Rechner der Serverinstallation nur kopiert?
Ist das bei "allen Datenbanken" so, also auch Oracle, MySQL, MariaDB, Postgres etc. ?
Wie kann ich denn prüfen ob die Firebird-DB sich in einem konsistenten Zustand befindet?
Das ist nämlich auch eine Frage die ich mir gestellt habe: Wenn man eine DB, so wie bei Firebird oder SQLite als Datei vorliegen hat, kann man dann zum Sichern der Daten einfach die komplette Datenbankdatei kopieren oder sollten vorher Backuptools Verwendung finden?
Wenn das Projekt fertig ist soll es in einem Netzwerk laufen, wo ich auf einem der Computer Firebird als Superserver installieren wollte.
Dazu hab ich auch noch eine Frage:
Ein Rechner erhält die Serverinstallation. Die anderen teilnehmenden Computer erhalten Client-DLL's richtig? Die liegen dann im selben Ordner wie auch das Lazarus-Programm? Müssen die installiert werden oder werden sie vom Rechner der Serverinstallation nur kopiert?
Ist das bei "allen Datenbanken" so, also auch Oracle, MySQL, MariaDB, Postgres etc. ?
- af0815
- Lazarusforum e. V.
- Beiträge: 6117
- 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: Allgemeines zum Umgang mit Datenbanken
Grundlegend empfehle ich besonders bei Windows einen Installer um die dlls und das Programm zu installieren, besonders dann wenn man es über mehere Rechner ausrollen will/muss. Zusätzlich ein entsprechendes Design, wo welche Dateien liegen. Programm, Dlls und DB im selben Ordner werden Probleme schaffen und das Paket zum Beispiel von einer IT zurückgewiesen werden. Programm und Dlls sind verträglich, da Windows aus guten Grund seit langen Side by Side Dlls zulässt. Beispiel ist da MSSQL da dort extra Bibliotheken für den Zugriff da sein müssen, das MS nicht für Lazarus direkt bereitstellt.
Bei den Clientbibliotheken, Grundlegend den Installer des Serverhersteller zu nehmen, ansonsten mit dem Installer s.o. Unter Linux normalerweise immer über die Softwareverteilung des Systems zu arbeiten.
Am Server kann es beide installation geben Server und Client. Bei MS ist das zum Beispiel so. Der Server und die Clientbibliotheken sind 2 paar Schuhe, Rest s.o.
Setup für Windows nehme ich InnoSetup. Und nicht vergessen, manche Dlls benötigen weitere Dlls, die unter Umständen auf frischen Systemen nicht vorhanden sind. Deswegen auch immer mal den Installer des DB Herstellers als erster dran lassen. Die installieren für ihre Treiber machmal runtimes nach. Wäre nichts neues wenn es auf manchen Systemen einfach nicht geht, besonders wenn ein neuer Mitarbeiter einen neuen PC bekommt
Bei den Clientbibliotheken, Grundlegend den Installer des Serverhersteller zu nehmen, ansonsten mit dem Installer s.o. Unter Linux normalerweise immer über die Softwareverteilung des Systems zu arbeiten.
Am Server kann es beide installation geben Server und Client. Bei MS ist das zum Beispiel so. Der Server und die Clientbibliotheken sind 2 paar Schuhe, Rest s.o.
Setup für Windows nehme ich InnoSetup. Und nicht vergessen, manche Dlls benötigen weitere Dlls, die unter Umständen auf frischen Systemen nicht vorhanden sind. Deswegen auch immer mal den Installer des DB Herstellers als erster dran lassen. Die installieren für ihre Treiber machmal runtimes nach. Wäre nichts neues wenn es auf manchen Systemen einfach nicht geht, besonders wenn ein neuer Mitarbeiter einen neuen PC bekommt

Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 90
- Registriert: Do 23. Dez 2010, 19:10
- OS, Lazarus, FPC: Windows 10/11 32/64bit, L 2.2.0 32bit, FPC 3.2.2 32bit
- CPU-Target: 32Bit
Re: Allgemeines zum Umgang mit Datenbanken
Hallo,
Frage, welche Lazarus Version hast du?
Ich habe auch eine Datenbankanbindung (ODBC, Windows 32bit) und das Programm läuft unter 2.0.8 ohne Probleme.
Ich habe dann das Programm mit 2.0.10 ohne Änderung neu übersetzt und habe auch das Problem bekommen.
Ist aber nur bei einer bestimmten Query. Wenn ich dort Refresh mache, erscheint diese Fehlermeldung.
Bei anderen Querys in dem Programm ist es nicht so.
Ich kann diesen Fehler nicht reproduzieren. Habe schon alles mögliche gemacht, Komponente ausgetauscht usw.
Das einzige was geholfen hatte, wenn ich die Query schliesse und neu öffne.
Ich wollte am WE mal die neue 2.0.12 installieren und es mit dieser versuchen, ob der Fehler noch vorhanden ist.
Ich bin daraufhin wieder zur 2.0.8 zurückgekehrt.
Gruß
Frage, welche Lazarus Version hast du?
Ich habe auch eine Datenbankanbindung (ODBC, Windows 32bit) und das Programm läuft unter 2.0.8 ohne Probleme.
Ich habe dann das Programm mit 2.0.10 ohne Änderung neu übersetzt und habe auch das Problem bekommen.
Ist aber nur bei einer bestimmten Query. Wenn ich dort Refresh mache, erscheint diese Fehlermeldung.
Bei anderen Querys in dem Programm ist es nicht so.
Ich kann diesen Fehler nicht reproduzieren. Habe schon alles mögliche gemacht, Komponente ausgetauscht usw.
Das einzige was geholfen hatte, wenn ich die Query schliesse und neu öffne.
Ich wollte am WE mal die neue 2.0.12 installieren und es mit dieser versuchen, ob der Fehler noch vorhanden ist.
Ich bin daraufhin wieder zur 2.0.8 zurückgekehrt.
Gruß
-
- Beiträge: 318
- Registriert: Di 17. Feb 2009, 10:44
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Re: Allgemeines zum Umgang mit Datenbanken
Hi,
ich nutze Lazarus 2.1.0 aus dem Trunk vom 08.03.2020 SVN Revision 62009M und FPC 3.3.1 auch Trunk.
Ich konnte halt die Zeilen mit dem Refresh ermitteln, weil dort das Programm halten blieb. Auskommentieren hat dann dazu geührt, dass das Grid nicht mehr aktualisiert wurde. Kunsstück, die Refresh's waren genau dafür.
Ich bin halt nicht der Datenbänker und Programmierer vor dem Herrn. Dass man, wenn man sich zum ersten Mal mit sowas beschäftigt, in solche Fallen rennt ist normal denke ich. Ich werde wohl auch an der Tabellenstruktur (keine Tabelle ohne Primärschlüssel) noch Änderungen vornehmen müssen.
ich nutze Lazarus 2.1.0 aus dem Trunk vom 08.03.2020 SVN Revision 62009M und FPC 3.3.1 auch Trunk.
Ich konnte halt die Zeilen mit dem Refresh ermitteln, weil dort das Programm halten blieb. Auskommentieren hat dann dazu geührt, dass das Grid nicht mehr aktualisiert wurde. Kunsstück, die Refresh's waren genau dafür.
Ich bin halt nicht der Datenbänker und Programmierer vor dem Herrn. Dass man, wenn man sich zum ersten Mal mit sowas beschäftigt, in solche Fallen rennt ist normal denke ich. Ich werde wohl auch an der Tabellenstruktur (keine Tabelle ohne Primärschlüssel) noch Änderungen vornehmen müssen.
- af0815
- Lazarusforum e. V.
- Beiträge: 6117
- 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: Allgemeines zum Umgang mit Datenbanken
Wenn du ohne PK auskommst, so würde ich immer einen PK verwenden. Eine GUID ist dafür normalerweise ok, weil nach der kannst du dann auch nicht sortierenErnstVolker hat geschrieben: ↑Fr 26. Feb 2021, 22:24Ich werde wohl auch an der Tabellenstruktur (keine Tabelle ohne Primärschlüssel) noch Änderungen vornehmen müssen.

Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 318
- Registriert: Di 17. Feb 2009, 10:44
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Re: Allgemeines zum Umgang mit Datenbanken
Dass es in Datenbanken auf unterschiedliche Weise möglich ist einen Autoincrement zu erzeugen ist mir auch schon aufgefallen. Unter Firebird 3 gibt man der ID bei Create Table ein "generated by default as identity primary key" mit auf den Weg. Früher (2.5) hat man mit Flamerobin sich automatisch einen Trigger und Generator erzeugen lassen. Wahrscheinlich passiert das heute intern, denn man findet so auf Anhieb Generator und Trigger nicht mehr. Postgres macht es übrigends ähnlich. Man definiert zwar ein Autoincrement, aber in z.B. pgAdmin findet man dann auch einen Trigger und einen Generator.
Es gibt auch die Möglichkeit ein Autoincrement neu starten zu lassen, wobei bei das im laufenden Betrieb von Datenbanken mit untereinander über PK-->FK Beziehungen zu Schäden an der Referentiellen Integrität führen kann, liege ich da richtig? Mir ist beim Erzeugen von diesen Schlüsselbeziehungen aufgefallen, dass man da hätte "CASCADE" einstellen können. Dann werden wohl Änderungen an Tabellen cascadierend durchgereicht. Ohne Störung der Referentiellen integrität?
Eine GUID ist laut Wikipedia ein Globally Unique Identifier. Gibt es hierfür in Lazarus Unterstützung sich sowas erzeugen zu lassen? Dann kann man den als PK laufen lassen.
Ich habe eine Tabelle nicht mit PK ausgestattet gehabt, weil es zum häufigen Löschen von Datensatzeinträgen kommen kann. Sprich der Anwender hat eine Auswahl getroffen die falsch ist und korrigiert werden muß. O.K. man kann mit Post arbeiten und nicht gleich in die Tabelle festschreiben lassen, sondern erst beim Schließvorgang des Auswahlfensters, wenn Irrungen korrigiert wurden und man der Meinung ist dass es jetzt in Ordnung sei. Ansonsten würde bei jedem Löschvorgang ein mit Autoincrement erzeugter PK zerstört werden und der nächste Integer Verwendung finden. Ob man das Ende des Integer-Wertebereiches im Laufe der Anwendungsnutzung erreicht denke ich zwar nicht, aber irgendwie läuft gedanklich eine Unsicherheit mit, weil man nicht weiß und nicht mitbekommt wo denn der PK jetzt ist. Kann man sich da auf die DB verlassen?
Kann man GUID's "verschenderischer" umgehen als mit Integer PK's?
Es gibt auch die Möglichkeit ein Autoincrement neu starten zu lassen, wobei bei das im laufenden Betrieb von Datenbanken mit untereinander über PK-->FK Beziehungen zu Schäden an der Referentiellen Integrität führen kann, liege ich da richtig? Mir ist beim Erzeugen von diesen Schlüsselbeziehungen aufgefallen, dass man da hätte "CASCADE" einstellen können. Dann werden wohl Änderungen an Tabellen cascadierend durchgereicht. Ohne Störung der Referentiellen integrität?
Eine GUID ist laut Wikipedia ein Globally Unique Identifier. Gibt es hierfür in Lazarus Unterstützung sich sowas erzeugen zu lassen? Dann kann man den als PK laufen lassen.
Ich habe eine Tabelle nicht mit PK ausgestattet gehabt, weil es zum häufigen Löschen von Datensatzeinträgen kommen kann. Sprich der Anwender hat eine Auswahl getroffen die falsch ist und korrigiert werden muß. O.K. man kann mit Post arbeiten und nicht gleich in die Tabelle festschreiben lassen, sondern erst beim Schließvorgang des Auswahlfensters, wenn Irrungen korrigiert wurden und man der Meinung ist dass es jetzt in Ordnung sei. Ansonsten würde bei jedem Löschvorgang ein mit Autoincrement erzeugter PK zerstört werden und der nächste Integer Verwendung finden. Ob man das Ende des Integer-Wertebereiches im Laufe der Anwendungsnutzung erreicht denke ich zwar nicht, aber irgendwie läuft gedanklich eine Unsicherheit mit, weil man nicht weiß und nicht mitbekommt wo denn der PK jetzt ist. Kann man sich da auf die DB verlassen?
Kann man GUID's "verschenderischer" umgehen als mit Integer PK's?
- af0815
- Lazarusforum e. V.
- Beiträge: 6117
- 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: Allgemeines zum Umgang mit Datenbanken
Grundlegend wenn du mit PK <-> FK Probleme hast, dann stimmt dein Design/Programm nicht. Ich verwende absolut kein Cascade, da das normalerweise beim richtigen Design nicht verwendet werden braucht. Entweder ich kümmere mich um die richtige Auflösung der PK/FK Sachen oder es kracht sowieso irgendwann. Und ein PK der sich ändert ist IMHO kein PK.ErnstVolker hat geschrieben: ↑Sa 27. Feb 2021, 10:00Es gibt auch die Möglichkeit ein Autoincrement neu starten zu lassen, wobei bei das im laufenden Betrieb von Datenbanken mit untereinander über PK-->FK Beziehungen zu Schäden an der Referentiellen Integrität führen kann, liege ich da richtig? Mir ist beim Erzeugen von diesen Schlüsselbeziehungen aufgefallen, dass man da hätte "CASCADE" einstellen können. Dann werden wohl Änderungen an Tabellen cascadierend durchgereicht. Ohne Störung der Referentiellen integrität?
Und so Sachen wie Personalnummer, SVnummer sind sowieso keine PKs. Denn wenn ein Kunde Stein und Bein schwört, das seine Personalnummern IMMER nur Nummern sind und die eindeutig, dann mache ich einen großen String. Wäre niocht das erste mal, das plötzlich ein zweiter Standort gemacht wird oder zugekauft wird und dort alles aganz anders ist oder die Stellen das System um und Plötzlich hast du Zahlen und Zeichen bunt gemischt. So ist mir das komplett egal, neue Spalte dazu und dort die neuen Sachen rein und die Apps angepasst. Manchmal nur die Views

S.o. das sind keine PKs sondern einfache Bewegungsdaten.Ich habe eine Tabelle nicht mit PK ausgestattet gehabt, weil es zum häufigen Löschen von Datensatzeinträgen kommen kann. Sprich der Anwender hat eine Auswahl getroffen die falsch ist und korrigiert werden muß.
GUID:
https://www.freepascal.org/docs-html/rt ... eguid.html
Sind leider 2xInt64 manche server können das
https://docs.microsoft.com/en-us/sql/t- ... rver-ver15
Wird bei dir also oversized sein. Ist aber sinnvoll wenn man zB. verteilte Datenbanken hat und dort Tabellen abgleichen muss. So hat jede Row ein eindeutiges Kennzeichen und das global. Damit kann man dann verteilte Tabellen eindeutig zusammenführen bzw. abgleichen. Bei Autoinc, hätte jeder Server unter Umständen die gleichen und die PK wären nicht eindeutig. Bei mir hängt das noch im Kopf herum, weil ich bei einer früheren Firma mit mehrerer Standorten das zusammführen und gleich halten durfte. Deswegen bin ich auch M$-SQL Server traumatisiert

Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 608
- Registriert: Do 27. Sep 2012, 00:07
- OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
- CPU-Target: x86_64-win64
- Wohnort: Hamburg
Re: Allgemeines zum Umgang mit Datenbanken
Ich würde in deiner Stelle bei Firebird immer Primäreschlüssel verwenden, gerade bei Tabellen die öfters bearbeitet werden. Wenn die Tabelle größer wird dann wird jedes bearbeiten, löschen extrem langsam. Irgendwann wurde bei uns das Ändern oder Löschen eines Datensatzes in einer Tabelle über 30 Sekunden lang, weil ich vergessen hatte den Befehl "Create Index ..." für diese Tabelle auszuführen hatte.
Ich definiere keine automatischen Primäreschlüssel sondern mit "IDNR INTEGER NOT NULL", dann definiere ich Generator für diesen Schlüssel und hole mir den Wert beim Speichern in die Tabelle, nicht gleich wenn der Benutzer auf + beim Datennavigator klickt.
Bei TZQuery von ZEOS-Komponenten, kann man das beim BeforeApplyUpdates machen(Ich verwende CachedUpdates). Bei TQuery ist es wahrscheinlich TQuery.BeforePost.
Ab Firebird 3 soll man BIGINT für Primäreschlüssel nehmen, falls es integer sein soll.
Für die Felder nach denen öfters gesucht wird, wie z.B. Auftragsdatum, solltest du auch Index erstellen weil die Suche extrem schnell wird, von mehrere Sekunden auf Milisekunden.
So definiere ich bei Firebird Tabellen:
Verwende bei Programmierung keine Embedded Version von Firebird, verwende immer Server. Du musst Firebird nicht unbedingt installieren, du kannst es in beliebigen Ordner entpacken, sogar in Unterordner von deinem Programm, dann kannst du das ganze als ZIP-Datei weitergeben. Du kannst, dann Server als Programm starten, es erscheint in Systemtray ein Symbol, damit kannst du es auch beenden.
In letzten Versionen von Windows funktioniert fbguard nicht richtig, deshalb muss man selber link erstellen, damit starten. Firebird SuperClassic Server kannst du so starten:
\Dein_Firebird_Ordner\bin\fb_inet_server.exe -a -m
Ich definiere keine automatischen Primäreschlüssel sondern mit "IDNR INTEGER NOT NULL", dann definiere ich Generator für diesen Schlüssel und hole mir den Wert beim Speichern in die Tabelle, nicht gleich wenn der Benutzer auf + beim Datennavigator klickt.
Bei TZQuery von ZEOS-Komponenten, kann man das beim BeforeApplyUpdates machen(Ich verwende CachedUpdates). Bei TQuery ist es wahrscheinlich TQuery.BeforePost.
Ab Firebird 3 soll man BIGINT für Primäreschlüssel nehmen, falls es integer sein soll.
Für die Felder nach denen öfters gesucht wird, wie z.B. Auftragsdatum, solltest du auch Index erstellen weil die Suche extrem schnell wird, von mehrere Sekunden auf Milisekunden.
So definiere ich bei Firebird Tabellen:
Code: Alles auswählen
CREATE TABLE AUFTRAG (
AUID INTEGER NOT NULL,
AUDATUM DATE
-- immer für jede Tabelle vor den Feldnamen Kürzel hinzufügen,
-- hier AU*, damit man bei Joins leichter unterscheiden kann
);
--primär schlüssel
ALTER TABLE AUFTRAG ADD PRIMARY KEY (AUNR);
--generator
CREATE GENERATOR AUFTRAG_AUNR_GEN;
-- sortier index
CREATE INDEX IDX_AUDATUM ON AUFTRAG(AUDATUM);
In letzten Versionen von Windows funktioniert fbguard nicht richtig, deshalb muss man selber link erstellen, damit starten. Firebird SuperClassic Server kannst du so starten:
\Dein_Firebird_Ordner\bin\fb_inet_server.exe -a -m
-
- Beiträge: 813
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz 2.2.6
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: Allgemeines zum Umgang mit Datenbanken
hmm...
Das Thema relationale Datenbanken (=RDBMS), dessen Design und Optimierung hier abzuhandeln würde wohl den Rahmen sprengen, zumal es da auch unterschiedliche Erfahrungen, Zugangswege, Philosophien und Traumata gibt.
Just my two cents....
für Tabellendeigns ohne Primary Key (=PK) muss man schon einen SEHR triftigen Grund haben - sonst hat jede Tabelle einen PK. Bei mir gilt das auch für Tabellen die ausschließlich zum Zweck der Verbindung über Fremdschlüssel benutzt werden (also n:m Relationen) weil sich die Handhabung vereinfacht und die Zugriffe schneller sind.
Sofern keine Standortsynchronisierungen oder ähnlich trickreiche Aktionen geplant sind sollte Integer oder BIGINT mengenmäßig dafür ausreichen. Bis man in einer Geschäftsanwendung so einige Millionen Datensätze zusammenbringt dauert es etwas. Die Schlüsselerstellung überlasse ich der DB und benutze nur eine solche die das auch sauber und sessionorientiert kann. Notfalls wird ein leerer Datensatz angelegt und der letzte neu generierte Schlüssel angefordert oder ein leerer Satz recycelt. GUIDs oder ähnliche Konstrukte suche ich zu vermeiden.
Das Schlüsselsystem der Datenbank (also die PFs, FKs) sind unabhängig von den Benutzereingaben und werden dem Benutzer nur in den seltensten Fällen gezeigt (etwa bei Debugging). Irgendwelche Personalnummern, SV-Nummern etc werden dafür nicht benutzt.
Ich selbst verwende keine Funktionen aus dem Bereich RI (=referentielle Integrität) wie zum Beispiel kaskadiertes Löschen weil das u.U. jede Datenbank anders handhabt. Um das Löschen und Anlegen von Datensätzen (=Zeilen, Tupel, Records etc) kümmere ich mich immer selbst. Oft werden Daten nur verborgen und nicht endgültig gelöscht.
Auch wenn in modernen PCs es oft nicht so aussieht: Datenbankzugriffe sind IMMER zeitktitisch. Daher ist es einfach guter Programmierstil wenn nur die Daten geholt werden die tatsächlich für die jeweilige Aktion nötig sind. SELECT * FROM gibt es grundsätzlich nur in wenigen sorgfältig abgewogenen Situationen (mir fällt aktuell keine ein). Eine Abfrage teilt sich grob in die Suche der Daten und deren Lieferung. Und je mehr (unnötige) daten mitgeliefert werden desto langsamer. Da liebe ich die (meisten)Jungs der Webdesign-PHP Fraktion die das meist völlig vernachlässigen.
Wo immer möglich sind die (Detail-)Daten über PKs abzufragen, dafür sind die ja "auch" da, denn die PKs sind immer in der DB indiziert (also quasi vorsortiert)
Suchabfragen (so nenne ich Abfragen an die Datenbank die nicht über PKs laufen) sind sorgfältig zu analysieren und ggfs auch mit dem Anlegen unterschiedlicher indizes zu optimieren. Letztlich bleibt einem selten erspart bei komplexen Abfragen Analysetools der jeweiligen Datenbank zu nutzen um den Zugriffsweg auf die Daten zu sehen. (aber da sind wir eh schon weit weg vom Basis-Know-How).
Letzlich kommt man an der Lernkurve bei DB Entwickling nicht vorbei wenn man eine DB-Anwendung schreiben möchte. Firebird kenne ich noch aus Delphi-Zeiten als es noch Interbase hieß. Für kleine Sachen nehme ich SQLite für den Rest MariaDB. Um MSSQL-Server und Oracle mache ich mittlerweile einen großen Bogen wegen alter Traumata
https://www.youtube.com/watch?v=oFcAQqKucL0
https://www.php-kurs.com/daten-struktur ... enbank.htm
https://www.amazon.de/gp/product/365817 ... e8fb6f8040
Das Thema relationale Datenbanken (=RDBMS), dessen Design und Optimierung hier abzuhandeln würde wohl den Rahmen sprengen, zumal es da auch unterschiedliche Erfahrungen, Zugangswege, Philosophien und Traumata gibt.
Just my two cents....
für Tabellendeigns ohne Primary Key (=PK) muss man schon einen SEHR triftigen Grund haben - sonst hat jede Tabelle einen PK. Bei mir gilt das auch für Tabellen die ausschließlich zum Zweck der Verbindung über Fremdschlüssel benutzt werden (also n:m Relationen) weil sich die Handhabung vereinfacht und die Zugriffe schneller sind.
Sofern keine Standortsynchronisierungen oder ähnlich trickreiche Aktionen geplant sind sollte Integer oder BIGINT mengenmäßig dafür ausreichen. Bis man in einer Geschäftsanwendung so einige Millionen Datensätze zusammenbringt dauert es etwas. Die Schlüsselerstellung überlasse ich der DB und benutze nur eine solche die das auch sauber und sessionorientiert kann. Notfalls wird ein leerer Datensatz angelegt und der letzte neu generierte Schlüssel angefordert oder ein leerer Satz recycelt. GUIDs oder ähnliche Konstrukte suche ich zu vermeiden.
Das Schlüsselsystem der Datenbank (also die PFs, FKs) sind unabhängig von den Benutzereingaben und werden dem Benutzer nur in den seltensten Fällen gezeigt (etwa bei Debugging). Irgendwelche Personalnummern, SV-Nummern etc werden dafür nicht benutzt.
Ich selbst verwende keine Funktionen aus dem Bereich RI (=referentielle Integrität) wie zum Beispiel kaskadiertes Löschen weil das u.U. jede Datenbank anders handhabt. Um das Löschen und Anlegen von Datensätzen (=Zeilen, Tupel, Records etc) kümmere ich mich immer selbst. Oft werden Daten nur verborgen und nicht endgültig gelöscht.
Auch wenn in modernen PCs es oft nicht so aussieht: Datenbankzugriffe sind IMMER zeitktitisch. Daher ist es einfach guter Programmierstil wenn nur die Daten geholt werden die tatsächlich für die jeweilige Aktion nötig sind. SELECT * FROM gibt es grundsätzlich nur in wenigen sorgfältig abgewogenen Situationen (mir fällt aktuell keine ein). Eine Abfrage teilt sich grob in die Suche der Daten und deren Lieferung. Und je mehr (unnötige) daten mitgeliefert werden desto langsamer. Da liebe ich die (meisten)Jungs der Webdesign-PHP Fraktion die das meist völlig vernachlässigen.
Wo immer möglich sind die (Detail-)Daten über PKs abzufragen, dafür sind die ja "auch" da, denn die PKs sind immer in der DB indiziert (also quasi vorsortiert)
Suchabfragen (so nenne ich Abfragen an die Datenbank die nicht über PKs laufen) sind sorgfältig zu analysieren und ggfs auch mit dem Anlegen unterschiedlicher indizes zu optimieren. Letztlich bleibt einem selten erspart bei komplexen Abfragen Analysetools der jeweiligen Datenbank zu nutzen um den Zugriffsweg auf die Daten zu sehen. (aber da sind wir eh schon weit weg vom Basis-Know-How).
Letzlich kommt man an der Lernkurve bei DB Entwickling nicht vorbei wenn man eine DB-Anwendung schreiben möchte. Firebird kenne ich noch aus Delphi-Zeiten als es noch Interbase hieß. Für kleine Sachen nehme ich SQLite für den Rest MariaDB. Um MSSQL-Server und Oracle mache ich mittlerweile einen großen Bogen wegen alter Traumata

https://www.youtube.com/watch?v=oFcAQqKucL0
https://www.php-kurs.com/daten-struktur ... enbank.htm
https://www.amazon.de/gp/product/365817 ... e8fb6f8040