komplette Zeile von Resultset SCHNELL in Array einlesen

Datenbanklösungen mit AOO/LO

Moderator: Moderatoren

Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von Stephan »

Hallo,

ich erzeuge ein Resultset, wie üblich, also prinzipiell so:

Code: Alles auswählen

'...
        oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext")
	oDataSource = oBaseContext.getByName(DB_name)
	oCon_3 = oDataSource.getConnection(sUser, sPassword)
	
	Redim oAbfrageergebnis()
	sql_string = "Select * FROM ""Person"" ORDER BY ""Nachname"" ASC"
	oStatement = oCon_3.createStatement()
	oStatement.ResultSetType = 1005
	oAbfrageergebnis = oStatement.executeQuery(sql_string)
Nun würde ich üblicherweise die Einzel-Daten z.B. so auslesen:

Code: Alles auswählen

Do While oAbfrageergebnis.Next
	Redim listeninhalt(10)
        For i = 0 To 10
               listeninhalt(i) = oAbfrageergebnis(i+1).String
               'listeninhalt() wird hier an ein Unterprogramm übergeben
        Next i
Loop
Kann ich das was das zweite Makro tut irgendwie beschleunigen?

Worum geht es insgesamt?
Ich muss ein Resultset mit ca. 120 Spalten und ca. 2000-5000 Zeilen in ein Grid (auf einem Dialog!) einlesen und dafür ist obenstehendes Vorgehen VIEL zu langsam.

MIr wäre auch eine ungewöhnliche Lösung recht (vielleicht lässt sich hiermit etwas anfangen: https://forum.openoffice.org/en/forum/v ... =Resultset ?), nur es muss halt schnell sein.



Gruß
Stephan
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von Stephan »

Eine Lösung habe ich nicht gefunden, aber ich möchte hier die Information hinterlassen das man unter Nutzung der Beispieldatei von hier:
https://forum.openoffice.org/en/forum/v ... =21&t=1645

Daten aus Base (letztlich also auch ein Resultset) ziemlich schnell in ein Calc-Tabellenblatt laden kann - auf meinem Testsystem ca 20 Spalten x 5000 Zeilen in 8 Sekunden. Hat mam Sie ersteinmal dort eingelesen kann man mit .getDataArray lesen und sie dann per .addRows() sehr schnell in ein com.sun.star.awt.grid bekommt.

Die 8 Sekunden klingen langsam und sind es auch, denn es ist unpraktikabel solange warten zu müssen bis man letztlich einen Dialog fertig initialisiert hat, aber die 8 Sekunden sind ca. 10-mal schneller als das Einlesen über Resultset-Array per Schleife.


Vielleicht hilft diese Information zukünftig jemanden.


Gruß
Stephan
F3K Total
********
Beiträge: 3704
Registriert: Mo, 28.02.2011 17:49

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von F3K Total »

Hallo Stephan,
wenn es nicht unbedingt das Grid sein muss, könntest du es mit dem DATASOURCEBROWSER versuchen:

Code: Alles auswählen

Sub S_Open_DataSourceBrowser
    Dim URL as New com.sun.star.util.URL
    Dim Args(5) as New com.sun.star.beans.PropertyValue
    Dim Dispatch As Object

    oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext")
    oDataSource = oBaseContext.getByName(DB_name)
    oCon_3 = oDataSource.getConnection(sUser, sPassword)
    sql_string = "Select * FROM ""Person"" ORDER BY ""Nachname"" ASC"
    URL.Complete = ".component:DB/DataSourceBrowser"
    Dispatch = StarDesktop.queryDispatch(URL,"_Blank",8)

    Args(0).Name = "ActiveConnection" 
    Args(0).Value = oCon_3 
    Args(1).Name = "CommandType"
    Args(1).Value = 2':Table/View  1 SQL 2Command:"select NACHNAME from A_16_Liste_Teilnehmer"
    Args(2).Name = "Command"
    Args(2).Value = sql_string
    Args(3).Name = "ShowMenu"
    Args(3).Value = True
    Args(4).Name = "ShowTreeView"
    Args(4).Value = False
    Args(5).Name = "ShowTreeViewButton"
    Args(5).Value = False
'und öffnen
    Dispatch.dispatch(URL, Args)
end sub
Gruß R
RobertG
********
Beiträge: 2033
Registriert: Fr, 13.04.2012 19:28
Kontaktdaten:

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von RobertG »

Hallo Stephan,

ich habe mich jetzt zum ersten mal überhaupt mit dem Gridcontrol eines Dialogs befasst. Bei größeren Datenmengen (hier 12 Spalten und etwas über 8000 Datensätzen) konnte ich erst einmal das Problem nachvollziehen.

Das Ganze scheint auch nachvollziehbar, wenn ich eine Abfrage erstelle und diese Abfrage bei direktem SQL an die Datenbank schicke. Will ich bei so einer Abfrage direkt zum letzten Datensatz scrollen, so benötigt die Abfrage dafür bei mir auch eine Zeit von ca. 8 Sekunden. Dies ist merkwürdigerweise bei mir nur bei der HSQLDB der Fall. Nutze ich die interne Firebird-Variante, dann geht das sofort. Der Dialog in Firebird ist dementsprechend auch viel schneller geladen als der in HSQLDB. HSQLDB eben ca. 8 Sekunden, in Firebird unter 2 Sekunden. Eine MariaDB (direkter Treiber) zeigt bei mir wie Firebird keine nennenswerte Verzögerung beim Laden von über 8000 Datensätzen direkt in den Dialog. Sobald ich dann allerdings über JDBC gehe wird das ganze wieder ausgebremst. Das muss etwas mit der Einstellung FetchSize zu tun haben, die leider beständig für die SQL-Anweisung auf 1 steht. Schau einmal hier: https://venkatsadasivam.com/2009/02/01/ ... etch-size/

Die Benutzeroberfläche von Base trägt dem anscheinend Rechnung. Mit einer Abfrage ohne direktes SQL scheint im Hintergrund der Dateninhalt beständig nachgeladen zu werden. Das direkte Bewegen zum letzten Datensatz erscheint deutlich schneller. Ich vermute, je schneller ich den Button nach der Abfrage betätige, desto langsamer erscheint das Ganze mir.

Also bin ich einen Schritt weiter gegangen und habe mir gesagt: Mach' es wie Microsoft. Täusche vor, dass alles da ist nur der Desktop ist noch nicht bedienbar.

Code: Alles auswählen

stSql = "SELECT * FROM ""Suchtabelle"" LIMIT 200"
Mit diesem Code erhalte ich die ersten 200 Datensätze aus meiner Tabelle und packe die schon einmal in den Dialog.
Dann erstelle ich eine 2. Prozedur, die an vom Dialog "on focus" ausgelöst wird - am liebsten wäre mir ja da der Scrollbalken des Tabellenkontrollfeldes.
Die Prozedur lädt nur einmal nach

Code: Alles auswählen

DIM inShow AS INTEGER
SUB GridFolgedatenZeigen
	IF inShow = 0 THEN
		inShow = 1	
		...
		stSql = "SELECT LIMIT 200 0 * FROM ""Suchtabelle"" "
		...
	END IF
END SUB
Das lädt dann den ganzen Rest.
Binde ich das an das Gridcontrol, dann ist das eben erst nach der Ladezeit bedienbar. Der Dialog mit dem Startinhalt ist aber da.

Gruß

Robert
RobertG
********
Beiträge: 2033
Registriert: Fr, 13.04.2012 19:28
Kontaktdaten:

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von RobertG »

Noch eine Ergänzung zu den Geschwindigkeiten:

Ich habe das gerade noch einmal mit einer Tabelle mit etwas über 30.000 Datensätzen und 15 Spalten versucht. Alles in die Tabelle eines Dialogs einzulesen dauert bei der internen HSQLDB ca. 24 Sekunden, bei der internen Firebird Datenbank 6 Sekunden.

Schaue ich mir das Ganze dann in einer Abfrage an, bei der SQL-Befehl direkt ausführen eingegeben ist, so braucht die HSQLDB nach dem Klicken auf "letzter Datensatz" 30 Sekunden, um wirklich den letzten Datensatz anzuzeigen. Bei Firebird ist das ganze unter einer Sekunde gemacht.

MariaDB mit der direkten Verbindung liefert hier wieder die gleiche Geschwindigkeit wie Firebird intern.

Irgendetwas mit der Javakonstellation steht da ziemlich auf der Bremse.
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von Stephan »

Also bin ich einen Schritt weiter gegangen und habe mir gesagt: Mach' es wie Microsoft. Täusche vor, dass alles da ist nur der Desktop ist noch nicht bedienbar.
Ich hoffe es ärgert Dich nicht, das Du davon nichts wissen konntest, weil ich zwischenzeitlich nichts geschrieben habe, aber meine Lösung dazu ist inzwischen ganz ähnlich:

Ich lade einige DAtensätze ins Grid und zeigen dann den Dialog zunächst nur mit .Visible an. Dadurch kann ich im Makro weiter DAten ladedn UND der Benutzer kann bereits in den sichtbaren Datensätzen scrollen.

Sobald im Makro alles verarbeit ist, lade ich per .AddRows(...) alle alle fehlenden Datensätze ins Grid und schalte den Dialog von .Visible auf .Execute.

Nachteil: das Grid ändert seine Scrollposition und der Anwender sieht u.U. seine ausgewählte Zeile nicht mehr und es wird dadurch ja auch nicht schneller, sondern erscheint dem Benutzer nur so.
Letzterer Eindruck wird noch verstärkt wenn man eine Fortschrittsanzeige auf dem Dialog anzeigt, gerade wenn man dazu ein Label-Feld nimmt und einblendet wieviel % geladen sind ist der 'Effekt' toll, noch besser als wenn man einen Ladebalken anzeigt.


Gruß
Stephan
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von Stephan »

Hallo Robert,
Noch eine Ergänzung zu den Geschwindigkeiten:

Ich habe das gerade noch einmal mit einer Tabelle mit etwas über 30.000 Datensätzen und 15 Spalten versucht. Alles in die Tabelle eines Dialogs einzulesen dauert bei der internen HSQLDB ca. 24 Sekunden, bei der internen Firebird Datenbank 6 Sekunden.
Nach meinen, in meiner vorstehendeen Antwort, angegebenen Implementierungsexperimenten, bin ich auf Python umgeschwenkt, weil ich weiß das es ein für das Grid passendes Daten-Array, wenn es denn erst einmal existiert, SEHR SCHNELL ins Grid geschrieben bekomme. Dadurch sollte es möglich sein an Python die Aufgabe zu übertragen das passende Array zu erstellen und aber ich kann den Rest in Basic machen (Letzteres ist mir wichtig, weiol ich derzeitig keine Zeit habe Python so gründlich zu lernen als das ich alles in Python machen könnte).

Seit gestern habe ich eine entsprechende Test-Implementierung fertig und obwohl ich noch etliche Details abklären muss (z.B. http://de.openoffice.info/viewtopic.php ... 52#p295252), kann das wird wohl mein zukünftiger Lösungsweg werden.

Es wird wohl viele Wochen dauern bis ich das alles detailliert geklärt habe und Zeit finde es hier im Forum zu dokumentieren, aber Du darfst sicher sein das ich das tue und ich würde Dich dann auch daraufhin ansprechen das Du diesen Weg in Deine Base-Dokumentation übernimmst.


Geschwindigkeit ist derzeitig ungefähr 2-3 Sekunden für 5000 Datensätze mit 25 Spalten aus einer MySQL-DB (=Gesamtzeit für Dialog plus Grid befüllen, vom Zeitpunkt des Makro-Starts bis der Dialog komplett fertig angezeigt wird), d.h. es ist, gegenüber Basic, sehr schnell aber nicht 'unendlich' schnell, denn z.B. 20.000 Datensätze dauern auch ca. 12-15 Sekunden.



Gruß
Stephan
cosmo17
*
Beiträge: 10
Registriert: So, 06.06.2021 11:15

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von cosmo17 »

Hallo, ich verfolge diesen Thread, da ich an der Verwendung von Gridcontrols interessiert bin. Vielleicht sollte es ein eigener Thread sein..

Waere es moeglich ein HSQl-Beispiel zu posten, weil ich lernen möchte, wie man das Raster aus einem Array auffüllt.
Darüber hinaus stellt sich die Frage - ist es möglich, die Daten im Raster direkt zu ändern oder werden zusätzliche Textfelder benötigt ?

Mfg & Danke
RobertG
********
Beiträge: 2033
Registriert: Fr, 13.04.2012 19:28
Kontaktdaten:

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von RobertG »

Hallo cosmo17,

ich habe das in das überarbeitete Handbuch übernommen und die Diaglog-Datenbank damit erweitert. Schau einfach auf https://www.familiegrosskopf.de/robert/ nach den Bearbeitungsversionen. Was ich da nicht mit rein gepackt habe ist die Verarbeitung größerer Datenmengen. Kann ich gegebenenfalls noch in die Datenbanken mit einbauen, nur ist die Beispieldatenbank eigentlich nur so gedacht: Schau, wie Dialoge funktionieren und wie Daten im Dialog angesehen und bearbeitet werden können.

Die Daten direkt im Raster zu ändern habe ich bisher nicht geschafft. In dem Beispieldialog sieht das so aus: Klick auf den Datensatz im Gridcontrol, Anzeige des Datensatzes in den Eingabefeldern darüber, abspeichern und Datenänderung im Gridcontrol anzeigen. Das ist vom Prinzip her das Verfahren, das ich auch in Webdatenbanken nutze. Unten zeige ich Tabellen an, mit einem Klick auf die Zeile befördere ich die Inhalte in die Formularfelder. Nach dem Abspeichern lese ich die Tabelle neu ein. Beim Gridcontrol muss das nicht die ganze Tabelle sein sondern lediglich der markierte Datensatz.

Gruß

Robert
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von Stephan »

cosmo17 hat geschrieben: Sa, 17.07.2021 10:18 Hallo, ich verfolge diesen Thread, da ich an der Verwendung von Gridcontrols interessiert bin. Vielleicht sollte es ein eigener Thread sein..

Waere es moeglich ein HSQl-Beispiel zu posten, weil ich lernen möchte, wie man das Raster aus einem Array auffüllt.
Darüber hinaus stellt sich die Frage - ist es möglich, die Daten im Raster direkt zu ändern oder werden zusätzliche Textfelder benötigt ?

Mfg & Danke
Schon diesen Thread gefunden?

http://de.openoffice.info/viewtopic.php?f=18&t=73707


Gruß
Stephan
cosmo17
*
Beiträge: 10
Registriert: So, 06.06.2021 11:15

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von cosmo17 »

@RobertG

Danke fuer die rasche Antwort. Die beiden Dialoge im Handbuch wurden schon erfolgreich adaptiert fuer zwei aehnliche. Zudem finde ich mehr info zu dialogen in Deutchen als in Englishen foren. Der meiste content scheint auf Calc zugeschnitten sein.

Eigentlich hatte ich vor mit einer gridcontrol im dialog die funktionalitaet einer tablecontrol zu simulieren, da in mancher hinsicht dialoge fuer kleinere datenmengen schneller laden als formen und keinen Einfluss auf groesse und position der naechsten form haben. Auch finde ich dialoge sehr geeignet fuer rasches dashboard reporting, hmm.. chart in dialog?
Nochmals Danke

mfg Gerhard


@Stephan

Hallo und danke fuer den link. Wenn das Os Spanish, die graue Masse auf Englisch programiert und man Deutsche Foren durchsucht sind solche links schwer zu finden. Aber mit Eurer Hilfe klappts dann doch

mfg Gerhard
RobertG
********
Beiträge: 2033
Registriert: Fr, 13.04.2012 19:28
Kontaktdaten:

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von RobertG »

Hallo Gerhard,

das mit dem Gridcontrol habe ich erst in den letzten tagen nach diesem und dem vorhergehenden Thread hinzugefügt. Wenn Du die Dialoge aus dem aktuell veröffentlichen Handbuch meinst, dann ist das Gridcontrol natürlich noch nicht da drin.

Diagramme habe ich bisher nur im Bericht (zur Zeit nicht funktionierend) und im Formular unter gebracht.

Im Dialog habe ich das probiert. Das scheitert wohl daran, dass Diagramme so etwas wie eigenständige Dokumente sind. Die werden auch im Writer über die OLE-Verbindung geholt.

Gruß

Robert
cosmo17
*
Beiträge: 10
Registriert: So, 06.06.2021 11:15

Re: komplette Zeile von Resultset SCHNELL in Array einlesen

Beitrag von cosmo17 »

@RobertG

Brilliantes Beispiel, herzlichen Dank.

lg
Gerhard
Antworten