Firebird - auf bereits vorhanden Datensatz prüfen

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von and4more »

Hallo liebes Forum,

habe noch mal einige Fragen zu Firebird-Datenbanken (Version 2,5). Kennt jemand von Euch eine Internetadresse, wo man Codebeispiele/Tutorials dazu findet wie man:

1.) performant nach bereits vorhandenen Datensätzen sucht. Meine Idee wäre:

Code: Alles auswählen

select NAME,VORNAME, GEBDATUM from TABELLE_XY where NAME = :NAME and VORNAME = :VORNAME and GEBDATUM = :GEBDATUM
wobei die Felder über SQLQuery.FieldByName('...') rausgesucht werden könnten. Gibt's da was Besseres?

2.) wenn der gesuchte Datensatz nicht gefunden wird, wie kann man das im Code abfangen, da ja dann ein leerer Datensatz rauskäme? z. B.:

Code: Alles auswählen

if (SQLQuery.FieldByName('...') = IsNull) then .... -> neuen Datensatz anlegen?


3.) wie kann ich elegant bei einer mittels referentieller Integrität gekoppelten Tabelle die ID der Person (ist nicht der Primärkey der abhängigen Tabelle) in die zweite, abhängige Tabelle übertragen? (geht so was dann automatisch oder muss es codiert werden?)

...und 4.) zählt bei Einfügen des Datensatzes der Primärkey automatisch nach oben oder muss ich sowas wie

Code: Alles auswählen

insert into TABELLE_UVW (U_ID) values (sum(U_ID)+1)
einfügen oder in Pascal

Code: Alles auswählen

 
with Dataset do begin
  Open;
  Last;
  i:=FieldByName('U_ID').AsInteger;
  Apend;
  FieldByName('U_ID').AsInteger:=i+1;
  Post;
end;
 


Danke schon mal im Voraus für Eure Mühe.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

TBug
Beiträge: 177
Registriert: Mi 2. Sep 2015, 11:09
OS, Lazarus, FPC: Lazaurus 2.2.4 FPC 3.2.2
CPU-Target: Windows 32/64bit

Re: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von TBug »

Wenn Du Deine Abfrage mit dem Code unter 1. machst, dann hat die ausführende Query entweder soviele Datensätze, wie gefunden werden oder eben keinen Datensatz, aber niemals einen leeren.

Darum brauchst Du nur die Anzahl der Datensätze zu überprüfen, die Dir das SELECT-Statement zurückliefert.
Wenn 1 dann UPDATE, wenn 0 dann INSERT.
Wenn > 1 dann hast Du ein Problem.


.

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von and4more »

...o.k. habe das Problem wohl nicht wirklich gut beschrieben: Es geht nicht nur alleine um die Anzahl der Datensätze, sondern auch darum, dass ich, wenn ein Datensatz bereits vorhanden ist, dessen ID brauche um in der gekoppelten Tabelle danach unter dieser ID einen neuen Datensatz anlegen zu können. Insofern ist der Punkt aber schon zur Hälfte beantwortet, denn wenn 0 rauskommt kann man ohne weitere Prüfung zu INSERT übergehen während bei 1 eine Prüfung der ID erfolgen müsste. Vielen Dank
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

TBug
Beiträge: 177
Registriert: Mi 2. Sep 2015, 11:09
OS, Lazarus, FPC: Lazaurus 2.2.4 FPC 3.2.2
CPU-Target: Windows 32/64bit

Re: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von TBug »

Dann holst Du Dir eben bei der Überprüfung auf Vorhandensein den kompletten Datensatz:

Code: Alles auswählen

SELECT * FROM TABELLE_XY WHERE NAME = :NAME AND VORNAME = :VORNAME AND GEBDATUM = :GEBDATUM
 

Dann hast Du gleichzeitig auch das Feld mit der U_ID, welche Du benötigist.


.

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von and4more »

...exakt. Meine Frage zielte aber auch ein bisschen darauf ab, ob dieses Vorgehen in Bezug auf Laufzeitverhalten optimal ist oder ob es da vielleicht 'ne bessere Lösung gibt?
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6209
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: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von af0815 »

Für 4) gibt es mehrer Gedankenansätze.

Der einfachste ist, einen Generator (oder AutoInc) zu verwenden. Du kannst dich halt nicht darauf verlassen das die IDs streng aufsteigend sind. Es enstehen Lücken von IDs in der DB, das ist normal und deswegen verwendet man diese IDs besser nicht für andere Zwecke (ZB. als Rechnungsnummer).
Der zweite ist, eine GUID zu verwenden. Bei der GUID ist man sicher das der Datensatz immer eindeutig ist, auch wenn die Datenbank auf einen anderen Server repliziert wird.

Der Ansatz den du verwenden willst, hat man maximal auf Desktop/Singleuser Datenbanken gemacht. Er ist insofern gefährlich, als das weitere Prozesse genau dasselbe machen können und dann hast du gleiche IDs bzw. unerklärliche Fehler.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6209
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: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von af0815 »

1) ist nur so performant, wie die indizes am Server konfiguriert sind. Es hängt stark von den Index Dateien ab, wie gut der executionplan ist.

3) Per Code, constrains helfen nur, die DB konsistent zu halten.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von and4more »

Danke schon mal für alle Antworten.
@af0815: Huh, das klingt wahnsinnig professionell, leider verstehe ich (=blutiger Anfänger :cry: ) nur Bahnhof, aber das klingt so dass ich's gerne umsetzen würde, da letztlich eine Datenbank schon mehrere Clienten bedienen können sollte. Was bitte meinst Du mit GUID. Ob der Primärkey eine strikte Reihenfolge hat interessiert mich eigentlich nicht und die Datenbank wohl auch nicht :wink: , bin kein Ordnungsfanatiker, aber was ist an meinem Ansatz falsch bzw. was könnte man bessern?
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6209
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: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von af0815 »

Schau mal in die LazInfos rein. Da gibt ein paar Grundlagen dazu.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von mse »

and4more hat geschrieben:3.) wie kann ich elegant bei einer mittels referentieller Integrität gekoppelten Tabelle die ID der Person (ist nicht der Primärkey der abhängigen Tabelle) in die zweite, abhängige Tabelle übertragen? (geht so was dann automatisch oder muss es codiert werden?)

MSEgui hat dafür die Komponenten "TFieldParamLink" und "TFieldFieldLink". "TFieldParamLink" kann die Status von master-slave DataSets synchronisieren und Feldwerte koppeln.
...und 4.) zählt bei Einfügen des Datensatzes der Primärkey automatisch nach oben oder muss ich sowas wie

Code: Alles auswählen

insert into TABELLE_UVW (U_ID) values (sum(U_ID)+1)
einfügen

Auf Firebird würde ich einen "before insert trigger" und einen "generator" verwenden. Flamerobin kann die automatisch anlegen, wenn im 'Create New Field' Fenster unter 'Autoincrement' 'Create new generator' und 'Create trigger' aktiviert werden.
Damit der von Firebird generierte Wert automatisch in den Datensatz des DataSet übertragen wird, muss bei MSEgui im entsprechenden Datenfeld bei "optionsfield" "of_refreshinsert" aktiviert werden. Neuere SQLDB Versionen haben diese Funktion auch, da kenne ich aber keine Details.

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von and4more »

@af0815: Also ich hab' mir die lazinfo0095 durchgelesen und finde nichts als Grundlagen, die mir bei meinen Fragestellungen nicht wirklich weiterhelfen, außerdem habe ich auch die diversen Datenbanktutorials betreffend Lazarus gelesen. Das sind aber letztlich alles Grundlagen ohne auf spezifische Fragestellungen einzugehen. Insbesondere beantworten sie nicht meine Frage, was Du mit GUID meinst, vielleicht einen Primärschlüssel? Der ist in beiden Tabellen vorhanden.

Autoinc ist in beiden Datenbanken für den Primärschlüssel eingestellt und der Primärschlüssel der ersten Datenbank ist der FOREIGN-Key der zweiten, abhängigen Tabelle, welche aber auch (natürlich) einen Primärkey besitzt. Danke bisher für die Antworten.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von and4more »

@mse: Hey, danke, guter Tipp. Hatte nochmal die Tabellen angeschaut und gesehen, dass Trigger und Generator gefehlt haben, obwohl Autoinc angekreuzt waren. Hatte gedacht, naiv wie ich bin, dass das automatisch beim Ankreuzen von Autoinc erfolgt.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6209
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: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von af0815 »

and4more hat geschrieben:Hatte gedacht, naiv wie ich bin, dass das automatisch beim Ankreuzen von Autoinc erfolgt.
Nicht bei Firebird, die autoinc sind stark abhängig von der gewählten Datenbank. Da du jetzt mit Autoin/Generator arbeitest, ist das mit den GUID hinfällig.

Das mit den GUIDs funktioniert in etwa gleich wie das mit den Generatoren. Man erzeugt einen eindeutigen Wert und trägt diesen dann als Primärschlüssel (PK) ein. Das kann abhängig vom System am Server oder lokal machen. Wenn man nicht die Spezialitäten eines Systems ausnutzt, kann man oft eine relativ von der Datenbank unabhängige Applikation schreiben und dafür ist eine GUID sehr gut geeignet. Das ist aber auch Ansichtssache, deshalb kann man über die verschiedenen Vorgehensweisen diskutieren.

Wenn du dein Tabellendesign fertig hast, würde ich mir einmal überlegen wieviele Daten in 1 Jahr bzw 5 Jahren hineinkommen und die Datenbank mal mit der Datenmenge mit testdaten füllen. Ist eine gute Übung für das befüllen, das geht normalerweise relativ einfach, muss ja nicht allzu sinnvoll sein was da hineinkommt und man bekommt beim Programmieren gleich ein Gefühl wie schnell oder langsam das ganze ist. Ausserdem sieht man so etwaige Fehler relativ schnelle wenn entsprechende Daten da sind. Kostet zwar etwas Zeit am Anfang, die holt man später aber 10 mal herein (Erfahrung). Denn wenn man schon beim Schreiben des Testgenerators Probleme hat, so sind die leichter zu Diagnostizieren als in eine gerade noch/nicht mehr funktionsfähigen Applikation.

BTW: Die LazInfos habe ich deshalb erwähnt, da dort ein paar Grundlagen und vor allen Begriffe aus der Datenbankwelt erklärt sind.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von and4more »

@af0815: Danke, entschuldige bitte wenn ich jetzt nerve, aber ich habe den Begriff GUID noch nicht gehört oder irgendwo gelesen. Was bedeutet das?
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Firebird - auf bereits vorhanden Datensatz prüfen

Beitrag von mse »

https://en.wikipedia.org/wiki/Globally_ ... identifier
Z.B.

Code: Alles auswählen

 
'{F3110855-1BD9-4E6D-98AD-670E2DA8AE2A}'
 

wobei "globally unique" ein wenig theoretisch ist.
Die vom Firebird Generator gelieferten Zahlenwerte brauchen etwas weniger Rechenleistung als Primärindex als GUID's.

Antworten