List()

Themen rund um den praktischen Einsatz von Firebird. Fragen zu SQL, Performance, Datenbankstrukturen, etc.

Moderator: thorben.braun

Antworten
Groffy
Beiträge: 78
Registriert: Do 12. Apr 2018, 23:14

Hallo,

ich hatte mir überlegt, dass ich diese Funktion nutzen könnte wenn ich Listen füllen möchte die z.B. alle Namen , oder alle vorkommenden Namen (Distinct) einer Tabelle enthalten sollen. Alle Elemente werden in einem BLOB mit dem angegebenen Trennzeichen übertragen und können dann auf Klientenseite mit einem einfachen String.Split() (c#) in ein Array/Liste kopiert werden. Bringt das irgendwelche Vor- oder Nachteile gegenüber einer herkömmlichen select [Feldname] from Tabelle ? In dem von mir angedachten Anwendungsbereich würden Ergebnismengen in der Größenordnung 10-100 Elemente vorkommen. Ich vermute, dass sich in diesen Größenordnungen nur sehr geringe Geschwindigkeitsunterschiede zeigen. Für welchen Zweck wurde diese Aggregat Funktion ursprünglich implementiert?

Beste Grüße
Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Hallo Volker,

warum diese Funktion mal implementiert wurde, kann ich dir nicht sagen. Aber ein Geschwindigkeitsvorteil könnte bei großen Datenmengen tatsächlich existieren. Du erhälst eine einzelne Zeile, statt 100 Zeilen, die du holen musst. Allerdings wird beim BLOB noch ein zusätzlicher FETCH notwendig, da in der eigentlichen Datenzeile nur die BLOB-ID steht. Das Holen des BLOBs erledigen die Client-Bibliotheken teilweise selbst.

Also kurzum: Bei großen Datenmengen könnte es tatsächlich Vorteile bringen.

Gruß
Martin
Martin Köditz
it & synergy GmbH
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Eine Anwendung für List() hat sich mir auch nie erschlossen.
Wenn man aber an eine Clientprogrammierung ins besonders mit C#/VB.Net o.ä. denkt, ist List() die schlechtest aller Wahlen.
Alleine der zusätzliche Programmieraufwand, da ich ja die schönen simplen Bindungen zwischen Daten, Listen, Controls noch durch zusätzliche Splits() ergänzen muss.
Und was die Performance angeht, so ist das Bilden der List(), Abrufen, zerlegen wieder in eine Liste zu packen auf jeden Fall langsamer.
Das Übertragen der Daten zum Client erfolgt ja auch nicht Satz, sondern Blockweise und komprimiert. Einen Vorteil gegenüber einem "Select [distinct] Name from Table" gibt es da überhaupt nicht.
So nehme ich eine DataTable, fülle diese mittels DataReader, hänge die DataTable an eine BindingSource und diese dann an diverse Controls.
Groffy
Beiträge: 78
Registriert: Do 12. Apr 2018, 23:14

Ich stimme Dir da zu, für eine Datenbindung an Controls macht das keinen Sinn.

Ich konnte auf die Schnelle nur bei SAP-Sybase eine fast identische Implementierung finden :

http://infocenter.sybase.com/help/index ... 67623.html

Die Funktion wird dort als SQL/2008 - Vendor extension aufgeführt...

In den dort aufgeführten Beispielen sehe ich auch keine zwingende Notwendigkeit für die Funktion...
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Eine Möglichkeit sehe ich da ggf. schon, und zwar bei sog. "rekursiven CTE's".
Das Beispiel wäre hier eine Stückliste, in der ich die Baugruppen nach Materialien auflöse, als Resultset erhalte ich dann z.B:

Baugruppe1 Material1
Baugruppe1 Material2
Baugruppe1 Material3
Baugruppe2 Material1
Baugruppe2 Material2
Baugruppe3 Material3

Per List() dann halt:
Baugruppe1, Material1+Material2+Material3
Baugruppe2, Material1+Material2+Material3

Noch interessanter wäre ggf. ein hierarchisches Beziehungssystem in dem ich den Pfad ermitteln will. Theoretisch könnte man das in der rekursiven CTE auch per Concat "||" erreichen, aber da ist ggf. die Länge beschränkt da es kein CLOB wäre.

Es kommt halt auf die Anwendung an, ob ich die Information tatsächlich nur als 1 Feld benötige oder nicht.

Bei der DB2/400 gibt es dafür dann SQL-Funktionen wie "SYS_CONNECT_BY_PATH(...)", für den M$-SQL-Server gibt es Beispiele mit Concat's.

Alles nur rein abstrakt.
Antworten