Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Temporäre Tabellen durch TFDMemTable ersetzen (https://www.delphipraxis.net/199809-temporaere-tabellen-durch-tfdmemtable-ersetzen.html)

Christian 21. Feb 2019 15:38

Datenbank: Interbase • Version: 2017 • Zugriff über: FireDAC

Temporäre Tabellen durch TFDMemTable ersetzen
 
Hallo,

mit dem ADS und den ADS-Komponenten konnten wir sehr bequem die Datensätze für z.B. einen Ausdruck zusammenstellen.

Zu SAP/ADS ist ja alles schon gesagt worden. Deshalb muss nun etwas Neues her, bevor irgendwann gar nichts mehr geht.

Hier mal ein sehr einfaches Beispiel:

Der Benutzer lässt sich Firmendatensätze in einem DBGrid anzeigen. Er selektiert dort dann beliebig viele Firmen und druckt dann eine Mitarbeiterliste der Firmen.

Es wird eine temporäre Firmen Tabelle erstellt und die selektierten Firmen rein kopiert, damit geht es dann mit einem join auf die Mitarbeitertabelle.

Da wir jetzt auf FireDAC / Interbase umstellen wollen und es die temporären Tabellen so in der Form nicht gibt, dachten wir, wir erledigen das mit TFDMemTable.

Also FDMemTableFirma mit den selektierten Firmen erstellt, FDQueryMitarbeiter auf Mitarbeiter erstellt, alles mit LocalSQL "verbunden"

und dann mit einer weiteren FDQueryAusdruck und LocalSQL den join abgesetzt.

Um aber in FDQueryAusdruck ein join aud FDQueryMitarbeiter machen zu können muss ich ja vorher erst ein FDQueryMitarbeiter.FetchAll machen.

Damit lade ich mir aber die komplette MitarbeiterTabelle in den Speicher.

Nun wollen/können wir uns ja keine Millionen von Mitarbeiterdaten in den Speicher laden, wenn wir am Schluss nur ein paar 1000 brauchen.

Kann man das also mit FireDAC eleganter lösen oder wie geht ihr da so vor?

LG

peterbelow 22. Feb 2019 13:08

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
TFDMemTable kann für dieses Problem nicht funktionieren, da die Daten darin ja nur auf dem Client liegen und damit ein auf dem Server abzuarbeitender Join nicht möglich ist.

Ich habe solche Probleme (wenn die Liste der foreign keys für die Auswahl zu lang für eine IN query ist) traditionell mit einer normalen Tabelle für temporäre Listen auf den Server gelöst. Zusätzlich zu dem Datenfeld für die Keys für den Join enthält die Tabelle ein Feld für eine numerische "query ID". Als Vorbereitung für den geplanten Join holt sich der Client eine neue Query ID aus einer Sequence auf dem Server. Dann fügt er die Keys für den Join (in deinem Beispiel die primary keys der ausgewählten Firmem) in die Tabelle ein, wobei alle neuen Zeilen die gleiche Query ID bekommen. Dann kann man die finale Query mit einem Join auf diese Tabelle formulieren und mit Hilfe der Query ID die zu verwendenden key auswählen. Wenn man die Ergebnisse verarbeitet hat kann man die Keys aus der Tabelle mit den temporären Daten einfach wieder löschen, sie haben ja alle die gleiche Query ID.

Dieses Verfahren funktioniert mit praktisch jedem Datenbankserver, auch wenn er keine temporären Tabellen anbietet, deren Inhalt nach Ende der Transaktion oder Session automatisch gelöscht wird.

Der Bottleneck ist dabei normalerweise das Einfügen der Keys für die Auswahl, jedenfalls wenn der Server nicht sowas wie Oracles array DML anbietet, um die Daten für viele neue Zeilen en bloc an den Server zu schicken. Mit Interbase kenne ich mich nicht so aus, vielleicht gibt es da was äquivalentes.

dataspider 22. Feb 2019 13:14

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
In Firebird nutze ich Temporary Tables (Preserve).
In Interbase sollte das eigentlich auch gehen.

Frank

mkinzler 22. Feb 2019 13:24

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
Globale Temporary Tables (GTT) gibt es in Interbase ab 7.5 und in FireBird seit 2.1

Christian 27. Feb 2019 15:23

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
Vielen Dank euch allen.

Der Ansatz von Peter ist sehr interessant, danke dafür.

Das mit den GTT muss ich mir nochmal durchlesen. Die sind halt leider nicht so bequem wie die temporären Tabellen im ADS
(z,B. select * into #temp1 from Tabelle, Temp Name muss nur innerhalb der Session eindeutig sein, Temptabelle löscht sich nach dem Schließen der Connection automatisch).
Das bekommt man natürlich alles auch nachgebaut.

Delphi.Narium 27. Feb 2019 15:48

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
http://docwiki.embarcadero.com/Inter...emporary_Table

Die ist doch, wenn man es richtig macht, nur innerhalb einer Session befüllt.

Wenn Interbase genauso "intelligent" ist wie Oracle, kann man eine derartige Tabelle in beliebig vielen Sessions gleichzeitig nutzen, ohne dass die irgendwie was von den anderen Sessions mitbekommen.

Aus Programmsicht hat also (so verstehe ich das) jede Session ihre eigene temporäre Tabelle.

Und statt
SQL-Code:
select * into #temp1 from Tabelle where condition
einfach ein
SQL-Code:
INSERT INTO table2 SELECT * FROM table1 WHERE condition;
erscheint mir jetzt nicht wie ein wesentlicher Programmieraufwand, sondern eher wie Standard-SQL.

mkinzler 27. Feb 2019 16:27

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
Zitat:

Die ist doch, wenn man es richtig macht, nur innerhalb einer Session befüllt.
Bei FireBird ist das so, man kann festlegen, ob die Daten beim commit automatisch gelöscht werden oder nicht. Bei Beendung der Sitzung werden diese auf jeden Fall bereinigt. Der Nachteil von GTT ist halt, dass die Struktur starr ist; Local Temporary Tables (LTT) sind "under consideration" (FireBird).

haentschman 28. Feb 2019 06:33

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
Moin...:P
Zitat:

Es wird eine temporäre Firmen Tabelle erstellt und die selektierten Firmen rein kopiert, damit geht es dann mit einem join auf die Mitarbeitertabelle.
...das verstehe ich nicht. :gruebel: Wenn ich eine Auswahl der Firmen hätte (ID Liste aus dem Grid z.B), da würde ich mir direkt die Daten aus der Datenbank holen...über einen join z.B. Was hat die Temporäre Tabelle für einen Sinn...ein Workaround?
Zitat:

damit geht es dann mit einem join auf die Mitarbeitertabelle.
...das SQL würde ich gern mal sehen.

Christian 28. Feb 2019 08:33

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
Moin,

Zitat:

Wenn ich eine Auswahl der Firmen hätte (ID Liste aus dem Grid z.B), da würde ich mir direkt die Daten aus der Datenbank holen...über einen join z.B. Was hat die Temporäre Tabelle für einen Sinn...ein Workaround?
Die selektierten Firmen können ja beliebig viele sein. In der Firmen ID Liste stehen letztendlich auch Firmen die du nicht selektiert hast. Du musst also erst eine Liste erstellen, in die du die Firmen kopierst, die du willst. Dann kannst du mit dem join kommen. Ein Join der kompletten Firmen Tabelle mit der Mitarbeiter Tabelle funktioniert nur, wenn die Anzahl der selektierten Firmen für die Where Klausel überschaubar ist, da die Datenbanken where ID in (1, 5, 10, 200,..., 1000000) nicht können, also nur eine bestimmte Anzahl an where Einträge verkraften.

jobo 28. Feb 2019 08:34

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
Ich weiß nicht, wo hier die Probleme liegen sollten.
Eine temporäre Tabelle ist offensichtlich das Vehikel, benutzerspezifische Daten so bereitzustellen, dass sie mit klassischen SQL Verfahren weiterverarbeitet werden können.
Was man dabei als "Temporär" bezeichnet, ist je nach Anwendungsfall mehr oder weniger treffend, der Clou ist ja wohl die individuelle (Session) Zusammenstellung der Daten. Andernfalls wären es normale Daten im Datenmodell, für alle von Bedeutung und mindestens lesbar. Je nach Machart (beim Hersteller) sind es dann eben Daten, die beim nächsten Arbeitsschritt oder in einer neuen Sitzung wieder weg sind.
"Notfalls" macht man es selbst, wie PeterBelow beschreibt. Dauerhafte, selbstgemachte "Temp"tables können dann sogar indiziert sein, was ggF. Vorteile hat, wenn tatsächlich "beliebig viele" Daten vom Benutzer ausgewählt werden.

Frickler 28. Feb 2019 09:26

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
Zitat:

Zitat von haentschman (Beitrag 1426576)
Moin...:P
Zitat:

Es wird eine temporäre Firmen Tabelle erstellt und die selektierten Firmen rein kopiert, damit geht es dann mit einem join auf die Mitarbeitertabelle.
...das verstehe ich nicht. :gruebel: Wenn ich eine Auswahl der Firmen hätte (ID Liste aus dem Grid z.B), da würde ich mir direkt die Daten aus der Datenbank holen...über einen join z.B. Was hat die Temporäre Tabelle für einen Sinn...ein Workaround?

Da wir auch gerade von ADS auf Firebird wechseln, kenne ich die Problematik.

Also... angenommen, Du kannst aus einer Liste (Grid, ListView, etc) Einträge auswählen, zu denen zusätzliche Informationen angezeigt werden sollen. Wenn das nur eine Handvoll Einträge sind, baust Du Dir eine SQL Anweisung a la "select bla from blubb where name in ('name1', 'name2', 'name3', ...)" wobei die "IN ()" Anweisung dynamisch aus den angehakten Listeneinträgen erstellt wird.

Wenn man aber in der Liste dutzende bis hunderte Einträge auswählen kann, wird eine "IN()"-Anweisung irgendwann unglaublich lahm (wenn nicht vorher das Limit für die Länge einer SQL-Anweisung überschritten wird).

Also baust Du Dir eine temporäre Tabelle, trägst dort alle Namen (IDs, Nummern, whatever) ein und JOINst diese gegen die Tabelle, welche die gewünschen Informationen enthält.

Natüüürlich kann man auch eine reguläre Tabelle nehmen, die musst Du aber nachher immer leeren. Eine temporäre Tabelle verschwindet von selbst.

p80286 28. Feb 2019 09:43

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
Wofür überhaupt eine temporäre Firmentabelle?
Pack die IDs der Firmen in ein Set und gut ist.
SQL-Code:
select ...
from firma join mitarbeiter ....
where
  firma.id in (set der firmenids)
Gruß
K-H

mkinzler 28. Feb 2019 10:38

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
Zitat:

Natüüürlich kann man auch eine reguläre Tabelle nehmen, die musst Du aber nachher immer leeren. Eine temporäre Tabelle verschwindet von selbst.
GGTs werden auch manuell geleert. Diese werden nur nicht automatisch gedroppt.

peterbelow 28. Feb 2019 12:18

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
Zitat:

Zitat von p80286 (Beitrag 1426592)
Wofür überhaupt eine temporäre Firmentabelle?
Pack die IDs der Firmen in ein Set und gut ist.
SQL-Code:
select ...
from firma join mitarbeiter ....
where
  firma.id in (set der firmenids)
Gruß
K-H

Die meisten Datenbankserver haben ein Limit für die Zahl der Einträge, die in einer IN-Liste enthalten sein dürfen, und außerdem sind solche Queries aufwendig zu parsen und ziemlich langsam verglichen mit einem Join mit effizient indizierten Tabellen.

p80286 28. Feb 2019 19:46

AW: Temporäre Tabellen durch TFDMemTable ersetzen
 
Das ist ja ein quantitatives Problem.
Die Alternative wäre ein/mehrere Inserts in eine (temporäre) Tabelle. Bei den paar Einträgen (vermute ich) fällt die Indizierung nicht ins Gewicht.

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:55 Uhr.

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