Oracle Ref Cursor mit TZQuery

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
Hitman
Beiträge: 512
Registriert: Mo 25. Aug 2008, 18:17
OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
CPU-Target: x86
Wohnort: Chemnitz

Oracle Ref Cursor mit TZQuery

Beitrag von Hitman »

Aktuelle plagt mich ein etwas spezielles Problem. Da hier einige mit größeren/komplexeren Datenbanken zu tun haben hoffe ich, ist jemand dabei, der eine Idee hat.
Es geht um den Aufruf einer Stored Procedure, die als InOut Parameter einen Ref Cursor zurück gibt. Jeder, der sich jetzt denkt "was zum Geier ist ein Ref Cursor": bitte weiter gehen, hier gibt es nichts zu sehen :D

In Java funktioniert das hervorragend mit einem Aufruf der Art:

Code: Alles auswählen

CallableStatement statement = connection.prepareCall("declare ret SPSCHEMA.TYPES.DB_RESULT;" +
        "begin SESSION.APP_ID := 123;" +
        "ret := PARAMS.DB_CURSOR_OPEN(" +
            "i_PARAM_ID => ?," +
            "io_CURSOR => ?" +
        "); end;");
 
statement.setInt(1, 12345);
statement.registerOutParameter(2, OracleTypes.CURSOR);
 
statement.execute();
ResultSet resultSet = (ResultSet)statement.getObject(2);
 
while (resultSet.next()) {
    System.out.println(resultSet.getString("SHORTNAME"));
}


Also kurz um: es wird PARAMS.DB_CURSOR_OPEN ausgeführt, der erste Parameter wird mit "12345" belegt, der zweite als Out Parameter wird in ein ResultSet gecastet und darüber wird dann iteriert.

Genau dieser letzte Punkt würde mich nun bei ZEOS reizen: wie kann ich mit diesem Cursor umgehen? Als Parameter Typ gibt es ja "ftCursor" ... aber wie kann ich den einem TZQuery zuweisen?

P.S.: TZStoredProc wäre zwar schön gewesen, bietet mir aber nicht die nötigen Freiheiten (Rückgabetyp per "declare" setzen, vor dem Aufruf noch globale Variablen setzen, etc.).

EgonHugeist
Beiträge: 93
Registriert: Di 17. Apr 2012, 22:41

Re: Oracle Ref Cursor mit TZQuery

Beitrag von EgonHugeist »

Hallo Hitman,

KEINE Component kann mit einem ref_cursor umgehen, da die OCI API dieses nicht her gibt und keiner weis, was die Referenz eigentlich darstellt. Ein cast tabel(call get_a_refcurser_for_a_table) via SQL würde einen table zurückgeben. Dies sollte auch funktionieren.

90% des oracle StoredProc Codes hab ich geschrieben. Nun fehlen mir jedoch eine Menge OCI Wissen, um alles fertig zu machen. Derzeit nicht unterstützt sind z.B. Nested-Tables, da hier der FPC ein ShowStopper auf dem DataSet Level ist: Es existiert KEIN FeldTyp, um ein Derartiges Object zu laden. Delphi unterstützt dies schon seit Version 3!

Ich habe mir die Zähne ausgebissen, um die Nested-Tables wenigstens auf DBC-Ebene zum Laufen zu bekommen. Bin jedoch gescheitert. Ich kann mit dem von OCI zurückgelieferten Pointer nicht arbeiten oder mach vorher etwas anderes falsch. Ich habe auch bereits Tests zu unseren Test-Suites hinzugefügt. Vielleicht schaust du da mal rein http://zeos.firmos.at/viewtopic.php?t=3671 und kannst mir ein wenig helfen? Derzeit kenne ich nur einen, der auf dem Sektor mehr Erfahrungen hat -> LudoB. Doch der hat genug mit den FPC DataSet Unterstützungen zu tun. Der Felder eines Arrays oder Tables kann ich schon bereitstellen, es knallt jedoch beim ersten fetch.

?stCursor? (wußte ich gar nicht) scheint mir ein User-Patch zu sein, ist aber, wie bereits beschrieben, Müll im Quellcode. Schau mal in function TZOracleAbstractResultSet.GetDataSet(ColumnIndex: Integer): IZDataSet; Da findest du meinen Kommentare ebenfalls und kannst sehen, wo ich scheitere.

Also erst mal müßte das OracleResultSet in der lage sein mit derartigen Typen umzugehen, bevor an der StoredProc oder dessen Statment weiter gebastelt werden kann.

Hilfe wäre wirklich wilkommen.

Grüße Michael, ZeosDevTeam
ZeosDevTeam

Hitman
Beiträge: 512
Registriert: Mo 25. Aug 2008, 18:17
OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
CPU-Target: x86
Wohnort: Chemnitz

Re: Oracle Ref Cursor mit TZQuery

Beitrag von Hitman »

Ohje, das klingt ja nach Spaß. Vielen Dank für die Einstiegspunkte! Deine Ausführung klingt mir danach, dass wohl die TZStoredProc am ehesten zum Erfolg führen wird. Ich werde mir das in einer ruhigen "Minute" mal zu Gemüte führen und schauen, ob mir ein paar gute Ideen kommen.

Nochmals vielen Dank und viele Grüße!
Andreas

EgonHugeist
Beiträge: 93
Registriert: Di 17. Apr 2012, 22:41

Re: Oracle Ref Cursor mit TZQuery

Beitrag von EgonHugeist »

Hi Andreas,

ob TZStoredProc oder TZQuery ist "Wurscht". Intern müßte erst mal alles vorbeitet sein, damit irgendein TZDataSet descendant damit umgehen könnte. Das gleiche gilt für den Dbc-Layer. Ich wollte das mit Zeos 7.1 fertig haben, laufe jedoch immer wieder in die gleich Sackgasse. Vielleicht findest du raus, wo ich scheitere? Wäre echt toll!


Grüßle aus Plauen, Michael
ZeosDevTeam

Hitman
Beiträge: 512
Registriert: Mo 25. Aug 2008, 18:17
OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
CPU-Target: x86
Wohnort: Chemnitz

Re: Oracle Ref Cursor mit TZQuery

Beitrag von Hitman »

Also wenn ich das richtig sehe, ist der RefCursor für das OCI das selbe wie ein Statement: http://docs.oracle.com/cd/B28359_01/app ... tm#i423493

Demzufolge müsste es doch möglich sein, aus dem Rückgabewert der SP (bzw. dem Out-Parameter o.ä.) ein TZOracleResultSet zu konstruieren. Ich schaue mal, ob ich ZEOS dazu bekomme, mir zumindest den Pointer durchzureichen :)

EgonHugeist
Beiträge: 93
Registriert: Di 17. Apr 2012, 22:41

Re: Oracle Ref Cursor mit TZQuery

Beitrag von EgonHugeist »

Mag sein (danke für den Link, öffnet mir ein weinig die schläfrigen OCI Augen), das wird jedoch alles nix bringen, solange Zeos mit dem Nested-Table(ref_cursor) nicht umbehen kann. Btw. UniDac kanns auch nicht..

Also grundsätlich müßte erst mal eine API vervollständigt werden, die zumindest solche Subobjekte verarbeiten kann. Wie beschrieben, kann ich vollständig (rekusiv) diese Objecte und deren Felder determinieren. Es Scheitert aber beim Fetch der Daten.

Ganz simples Bsp. von unseren Tests: 'SELECT * FROM SYSTEM.AQ$_QUEUES'
Hier verteckt sich auch eine NestedTable, den Zeos dir dezeit nicht anzeigt. Es wird dir jedoch helfen, meine API zu prüfen(ohne eigenen Code), und (so hoffe ich) mir die Augen zu öffnen, wo ich was falsch mache.. Teste es mal, wenn du magst.

Grundsätzlich: Wenn du derartige Dinge mit Zeos verarbeiten möchtest, wird die mit dem FPC wirklich nur die DBC ebene übrig bleiben, da die DataSets vom FPC nichts derartiges unterstützen (keine: Interfaces, Pointer, Classes, Objekt, unsigned typen, RawbyteStrings etc, halt alles, was der FPC variant derzeit nicht verarbeiten kann)
ZeosDevTeam

Antworten