Seite 1 von 1

Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Fr, 29. Jul 2022 15:30
von dtmackenzie
Nur ein paar einfache Funktionen die ich immer benutze um SELECT-Befehle als String auszuführen und Ergebnisse zu holen...
Die erste 3 liefern die Ergebnisse in aResult zurück, sonst sollte alles selbsterklärend sein, glaube ich.
Vielleicht nützlich für die, die gerade mit Postgres anfangen.

Der akt. Code liegt nun in der Wissensbasis:
https://www.xbaseforum.de/viewtopic.php ... 34#p142734

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 02. Aug 2022 13:03
von brandelh
das wäre was für die Wissensbasis

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 02. Aug 2022 13:19
von Marcus Herz
Ich würde, wenn ich es schon neu aufsetze, immer Array mit Dataobjects zurückgeben, vor allem wenn ich mal mehr Felder verwende, dann komm ich mit Arraypositionen schnell ans Limit der Lesbarkeit

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 02. Aug 2022 13:32
von dtmackenzie
Hallo Hubert,
wie ginge das am Besten, mit Verknüpfung?

Hallo Marcus,
ich habe nicht viel mit Dataobjects gearbeitet, aber ich glaube zu verstehen, was Du meinst. Schöne Idee, da hast Du Recht, es wäre doch viel besser, mit Feldnamen anstatt Arraypositionen zu arbeiten. Aber was kommt denn als Feldname wenn man eine berechnete Spalte im SELECT hat?

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 02. Aug 2022 13:34
von Marcus Herz
Du kannst der berechneten Spalte einen Feldnamen geben:

Code: Alles auswählen

select max(irgndwas) as maxfeld from ...
dann heisst die Spalte maxfeld

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 02. Aug 2022 13:36
von dtmackenzie
Das ist super, genauso wie ich es mir erhofft hätte, Danke Marcus!
Ich probiere das mal aus...

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 02. Aug 2022 13:44
von Jan
Xbase++ hat das SELECT um ein "INTO objecs" erweitert. Damit wird das Ergebnis des SELECT in ein Array geschrieben, dessen Sätze DataObjects mit den Satzinhalten und den Feldnamen sind. Klappt zumindest auf dbf ganz hervorragend. Nur leider etwas langsam. Wie das auf SQL wäre (wo ich ja letztendlich hin will) habe ich noch nicht getestet.

Jan

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 02. Aug 2022 14:45
von dtmackenzie
Hallo Jan,
Du meinst damit "Universal SQL" mit SELECT direkt im Code geschrieben?
Hat auch Charme, aber ich benutze nur "Pass-Through SQL" mit SELECT als String, ist ja flexibler.
Nur "roh" ist es ziemlich unlesbar im Vergleich, deshalb diese Wrapper-Funktionen.
Diese Funktion wäre also das von Marcus angeregte Äquivalent zum von Dir vorgeschlagenen SELECT... INTO...

Code: Alles auswählen

***************
PROC AOSelect(aResult, cSelect)
// Array of DataObjects from SQL SELECT
LOCAL nWA:=SELECT(), oStmt1:=DacSqlStatement():fromChar(cSelect)

ASIZE(aResult, 0)

// USQL_RESULT_ARRAY funktioniert nicht?
oStmt1:build():query(USQL_RESULT_WORKAREA, "ASelWA")
DBEVAL({|| AADD(aResult, ScatterIntoDataObject())})
CLOSE ASelWA

SELECT (nWA)
RETURN


***************
FUNC ScatterIntoDataObject()
LOCAL oDO
SCATTER NAME oDO
RETURN oDO
P.S. Ich weiß nicht, ob es eine Standard-Funktion wie ScatterIntoDataObject() gibt - habe ich aber nicht in der Hilfe gefunden, auch nicht die in AASelect() benutzte Funktion Scatter(), die jemand mir irgendwann netterweise verraten hat...

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 02. Aug 2022 15:04
von Jan
David,

es gibt natürlich ein SCATTER, und dazu passend das GATHER. Ein

Code: Alles auswählen

Scatter Name oData
schreibt den aktuellen Satz der aktuellen Workarea in ein DataObject. Schau Dir mal die Hilfe dazu an, es gibt diverse Parameter um das zu steuern. Wie welche Felder, welche Workarea, usw.

Jan

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 02. Aug 2022 15:53
von dtmackenzie
Jan,

ja, ich weiß, SCATTER NAME benutze ich schon in ScatterIntoDataObject()!

Es ging mir darum, ob es dies als Funktion anstatt als Befehl gibt, damit ich sie einfach im DBEVAL()-Codeblock benutzen kann.

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 02. Aug 2022 17:46
von Marcus Herz

Code: Alles auswählen

#command SCATTER NAME <foo> [IN <ncWorkarea>] [<add:ADDITIVE>] => _scatterObject(  nil , @<foo>, <(ncWorkarea)>, [<.add.>]  )
Aber es ist überhaupt keine gute Idee, das als Funktion in dbeval zu schreiben. Da ist die Wrapper funktion sinnvoller

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Do, 04. Aug 2022 16:02
von brandelh
dtmackenzie hat geschrieben: Di, 02. Aug 2022 13:32 Hallo Hubert,
wie ginge das am Besten, mit Verknüpfung?
da gibt es keine festen Vorschriften, aber ich mache das so, dass ich im ersten Beitrag - versuche - alle nötigen Infos zu Zweck und Inhalt, sowie genug Suchbegriffe ganz am Ende aufzunehmen.
Dann hänge ich die ZIP an, bei kleinen Texten kann man die auch einfach per Code Tag rein hängen.
Also im Prinzip dein erster Beitrag mit Ergänzungen, die können natürlich auch von anderen angehängt werden, aber Diskussionen sollte man in der Wissensbasis nach einer gewissen Zeit löschen.

Ich schreibe immer rein, dass die neueste ZIP immer im ersten Beitrag steht, und tausche die alten gegen neue aus.
Die Infos über die neue Version wird aber als normaler Beitrag angehängt, sonst sieht es keiner ;-)

Man könnte natürlich auch LINKS auf z.B. hier setzen, aber viele übersehen bei den vielen Diskussionsbeiträgen (hier ja durchaus erwünscht) leicht die wichtigen Ergebnisse.

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Fr, 05. Aug 2022 11:54
von dtmackenzie
Hallo Hubert,

ist erstmal gemacht, habe im Moment leider wenig Zeit für Ergänzungen (stehe kurz vor Urlaub)...
Ich habe AASelect() entfernt, die von Marcus angeregte AOSelect() ist viel lesbarer im Gebrauch, also sehe ich keinen Bedarf mehr für AASelect(), wäre eher schlechte Praxis.

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 11. Okt 2022 8:33
von dtmackenzie
Tja, der lesbarste Code ist leider nicht immer der schnellste...
Deshalb habe ich AASelect() als Alternative zu AOSelect() doch wieder eingefügt.

Ich habe inzwischen die Erfahrung gemacht, dass bei großen Datenmengen ein zweidimensionales Array deutlich schneller als ein Array von DataObjects ist, sowohl in der Funktion selbst als auch bei der nachfolgenden Bearbeitung.
Trotzdem wäre aber weiterhin eher AOSelect() zu empfehlen in Fällen wo das Performance keine große Rolle spielt.

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 11. Okt 2022 9:14
von Jan
Stimmt. DataObjects sind erheblich langsamer als ein reines Array.

Aber DataObjects sind halt bequem. Man kann jedes Feld direkt mit seinem Namen ansprechen. Xbase++ bietet Funktionen an das direkt einzulesen oder wegzuschreiben. Ich habe viel mit SCATTER und GATHER gemacht, und spiele jetzt gerade sehr viel mit dem SELECT rum. Ist einfach genial wie ich da die Sätze in nullkommanichts ausgelesen bekomme. Nicht ganz so schnell wie das Ausfiltern über einen SCOPE, aber halt vollkommen unabhängig von DB-Funktionen. Das ist für mich ein toller Einstieg in den Umstieg auf SQL-Tabellen.

Jan

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 11. Okt 2022 9:50
von dtmackenzie
Jan,
ich stimme Dir voll und ganz zu - und SQL macht auch wirklich Spaß!
Zum Beispiel, eine der schönsten Sachen an SQL SELECTs im Vergleich zu dBase-typische ISAM ist, finde ich, die Kontextunabhängigkeit.
Wenn man Daten holen will mitten in einem großen, komplexen Programm wo vielleicht nicht mal klar ist, welches Workarea aktuell ist (z.B. in Funktionen, die für mehrere Workareas benutzt werden), dann kann man einfach schreiben was man haben will ohne dass man Workarea, akt. Datensatz, Index, Filter, Scope u.s.w. alles vor der Datenbeschaffung speichern und nachher wiederherstellen muss!

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 11. Okt 2022 10:01
von Manfred
Hallo David,
wenn Du aber mit Aliasen arbeitest, ist das auch egal in welcher Workarea gerade was steht. Da muß nichts hin und her geschaltet werden. Damit arbeite ich schon seit vielen Jahren. Wobei ich mir in meiner DB Klasse den Selectbereich merke und dann über oKlasse:nArea-> arbeite. Das ist m.E. also nicht der Vorteil von SQL. Ich denke mal, das könnte man vergleichen mit dem was ich hier gerade beschreibe. Man muß bei SQL ja auch die einzelnen Tabellen angeben, die man abfragen möchte. :wink:

Re: Einfache Wrapper-Funktionen für SQL SELECT-Befehle

Verfasst: Di, 11. Okt 2022 10:44
von Jan
Hallo David,

stimmt.

Um das mal klar zu sagen: Seitdem Alaska die Scopes eingeführt hat (war das mit der 1.82?) bin ich begeisterter Fan davon. Und es war in all den Jahren Gewohnheit geworden das mit dem Sichern des aktuellen Index etc. Da muß ich gar nicht mehr nachdenken, das fließt automatisch aus den Fingern. Und ist ja halt auch wirklich schnell.

Aber mit dem SELECT und all den dazu von Alaska passend entwickelten Funktionen ist das halt noch viel einfacher geworden. Ja, ich mußte mir da meine Funktionen schreiben, die da ordentlich mit umgehen können. Weil Xbase++ da halt noch diverse Bugs drin hat, und das auch noch nicht vollständig umgesetzt hat (jedenfalls nicht bei Zugriff auf dbf). Und eben die SQL-Sachen doch manchmal anders arbeiten als gewohnt (so sind die Strings in den DataObjects nach dem Einlesen automatisch immer direkt getrimmt, was die Ausgaben von verketteten Werten erstmal überraschend falsch aussehen ließ. Weil die Zeichenketten eben nicht mehr die Länge des Tabellenfeldes haben wie man das von dbf gewohnt ist).

Aber dennoch - ich bin gerade dabei mein eigenes Projekt komplett darauf umzustellen. Was natürlich immer mal wieder bedeutet das ich meine Denke doch noch mal anpassen muß. Oder meine Funktionen. Aber wenn ich damit durch bin dann ist mir egal ob ich da jetzt auf dbf oder SQL mit zugreife. Es klappt so oder so. Und ich habe nebenbei auch noch meinen Code erheblich verschlankt.

Und das alles ohne Klassen. Manfred hat mal vor vielen Jahren seine Datenbankklasse vorgeführt. Ich hatte damals nur staunend zugehört. Und mich gefragt wofür das alles gut sein soll. Frei nach dem Motto "Warum einfach wenn es auch kompliziert geht". Inzwischen verstehe ich ihn da wesentlich besser. Und mach trotzdem immer noch keine Klassen - beliebter Diskussionspunkt in unseren regelmäßigen XUG-Treffen um mich zu ärgern :-D . Vielleicht ginge das damit ja teilweise erheblich eleganter. Aber Xbase++ ist da halt so gut das ich das auch mit Funktionen machen kann.

Jan