-
SQLGetData richtig aufrufen
Hallo,
beim abrufen von Daten des Typs SQL_NUMERIC mit dem
SQLGetData API werden Nachkommastellen abgeschnitten.
In der Beschreibung wird zwar darauf hingewiesen das mit einem erneuten Aufruf von SQLGetData die restlichen Werte zurückgeliefert werden, jedoch hab ich dies nicht hinbekommen.
Kann mir da jemand helfen ?
Bsp:
dow SQLGetData (ptr_StatementHandle:
idx:SQL_NUMERIC:
%addr(Daten):%size(Daten):
%addr(WertLen)) <> SQL_SUCCESS;
...
...
enddo;
-
Bei numerischen Werten muss als Länge, hier %size(Daten), in der Form "AnzStellen * 256 + AnzNk" angegeben werden.
SQL_NUMERIC ist Zoned:
d MyVar s 11 2
SQLGetData (ptr_StatementHandle:
idx:SQL_NUMERIC:
%addr(MyVar):11 * 256 + 2:
%addr(WertLen))
SQL_DECIMAL ist Packed:
d MyVar s p 11 2
SQLGetData (ptr_StatementHandle:
idx:SQL_DECIMAL:
%addr(MyVar):11 * 256 + 2:
%addr(WertLen))
Analog ist mit anderen Feldformaten umzugehen.
PS:
Der schnellere (performantere) Weg ist SQLBindCol, da dieser Aufruf nur 1 Mal nach dem SQLPrepare erforderlich ist und nach einem SQLFetch die Daten sofort zur Verfügung steht.
http://publib.boulder.ibm.com/iserie...rzadpmst37.htm
-
Hallo,
erstmal vielen Dank für die Antwort hat soweit wunderbar geklappt. Ich verwende nun auch den API SQLBindCol.
Allerdings habe ich noch Probleme beim Abrufen der Daten für ein BLBDTA Feld. Nach dem Fetch kommt nichts zurück.
Hab' ich da noch was vergessen ?
Definition in der DDS
A BLBDTA 10000 TEXT('BLBDTA')
A VARLEN(50)
SQLBindCol (ptr_StatementHandle: idx :
DescribeCol.Feldtyp :
%addr(Daten) + RecPos :
(DescribeCol.Felddef * 256) +
DescribeCol.FeldScale :
%addr(WertLen) );
-
Bei BLOB's muss man unterscheiden, ob die Daten direkt (SQL_BLOB, SQL_CLOB, SQL_DBCLOB) bearbeitet oder als sog. LOB_LOCATOR.
Technisch gesehen ist die Arbeit mit LOCATOR einfacher, da nicht der gesamte BLOB gelesen wird. Vor allem nicht, wenn man ihn vielleicht gar nicht benötigt.
Über den Locator erhält man ein Handle, für den dann extra Zugriffe benötigt werden (SQLGetSubString):
http://publib.boulder.ibm.com/iserie...rzadpmst82.htm
Prüfe mal den Feldtyp, der beim DescribeCol übergeben wurde.
-
Zitat von Fuerchau
Bei BLOB's muss man unterscheiden, ob die Daten direkt (SQL_BLOB, SQL_CLOB, SQL_DBCLOB) bearbeitet oder als sog. LOB_LOCATOR.
Technisch gesehen ist die Arbeit mit LOCATOR einfacher, da nicht der gesamte BLOB gelesen wird. Vor allem nicht, wenn man ihn vielleicht gar nicht benötigt.
Über den Locator erhält man ein Handle, für den dann extra Zugriffe benötigt werden (SQLGetSubString):
http://publib.boulder.ibm.com/iserie...rzadpmst82.htm
Prüfe mal den Feldtyp, der beim DescribeCol übergeben wurde.
übergeben wurde SQL_VARCHAR
-
Das hat mit BLOB's ja nichts zu tun.
Du musst bei SQLBindCol die Länge eines Feldes abhängig vom Feldtyp übergeben.
Bei SQL_DECIMAL, SQL_NUMERIC also 'Stellen * 256 + Nachkomma', bei Zeichenfeldern aber wieder Original '%size(MyField)'.
Du benötigst also verschiedene SQLBindCol !
Die ILE-Definition des VARCHAR-Feldes ist:
D MyVarChar s 10000 varying
Wobei das Feld dann tatsächlich 10002 Bytes groß ist, 2 Byte für die Länge des Inhaltes.
%size(MyVarChar) liefert die physische Größe, also 10002
%len(MyVarChar) liefert die Länge des Netto-Inhaltes
-
** Hand vor den Kopf schlag **
Klar, so bau ich mir auch meine Ergebnis_ds zusammen.
Das mit den verschiedenen SQLBindCols funktioniert.
Hab jetzt 3 verschiedene Aufrufe gemacht. Bin zwar noch skeptisch ob das alle für mich in Frage kommenden Feldtypen abdeckt, aber schau' mer mal......
Danke für die schnelle Hilfe.
sim
-
Wofür schlägst du dich denn mit den CLIAPI's rum ?
Gehts nicht mit Standard-SQL bzw. dynamischem SQL ?
-
Nun ja, für einfache Sachen verwenden wir dies auch.
Im Moment haben wir schon ein selbst gestricktes Serviceprogramm bzw ne Prozedur an der man jegliche Art von SELECT-Statement übergeben kann und die dann ein Ergebnis Feld zurückliefert das dann einfach in die entsprechende ds gestellt werden kann
Bsp:
dow sql_exec('select feld1, feld2, feld3, .... from datei... where....');
kunden_ds = sql_ergebnis
....
enddo;
wobei kunden_ds ne datei bschreibt (extname....)
Dies haben wir per SQLDA lösen können.
Das Problem hierbei ist das immer nur ein SQL-Statement ausgeführt werden kann. Dadurch ist es nicht möglich verschachtelte SQL Abfragen mit diesem Tool zu erstellen.
Wenn wir dies über die APIs hinkriegen kann ich dies ja selber steuern und somit auch mehrere SQL's
verschachtelt ausführen.
Das andere wäre ja auch zu einfach. ;-)
Praktisch wäre natürlich ne RPG Anweisung a la: %sql
*träum*
-
Aber wie hältst du es dann mit den variablen Strukturen und Feldtypen ?
Die Service-Routine müsste Funktionen wie Open(SqlString), GetField(Name), Close() usw. anbieten, da ja über die Struktur variabler Felder erst zur Laufzeit etwas bekannt ist.
Das RPG-Programm selber kann ja nicht mit dynamischen Strukturen umgehen.
(wobei hier die Frage aufkommt, wie du dynamische Strukturen denn statisch bindest ?)
Ich stelle mir die Lösung für ILERPG schon reichlich kompliziert vor. In Java ist das ganze ja durch das SQL-Package gelöst (ähnlich wie ADO/DAO/ODBC auf dem PC).
Trotzdem:
Was ist denn Sinn und Zweck solcher dynamischer SQL's, die eigentlich besser innerhalb des jeweiligen Programmes laufen sollten ?
PS:
Das mit "Kunden_DS = SQL_Ergebnis" kann ja nicht funktionieren, solange nicht der "Select" ein "Select *" ist, und dann brauchst du kein Service-Programm.
-
Also,
das Service Programm wird tatsächlich Prozeduren wie z.Bsp
sql_openstatement(STATEMENT) --> liefert handle
sql_closestatement(...)
sql_execstatement.... etc enthalten
dieses Servicepgm kann ich dann in allen ILE programmen verwenden ohne das ich umständlich mit emb. sql etc hantieren muß. einfach der prozeduren aufrufen, fertig.
Richtig dynamisch im Sinne von irgendeinen SQL aus ner Datei lesen und den ausführen geht natürlich nicht.
Aber immerhin kann ich in meinem jew. Programm mit 3 kurzen Anweisungen die SQLs ausführen. Vorher noch Statement definieren und Ergebnis_ds und es läuft.
Sinn und Zweck:
Arbeitserleichterung, siehe oben
Ok, das mit der Kunden_ds und dem select war im Beispiel falsch. Die Kunden_ds bzw die jeweilige "Ziel_ds" muß natürlich entsprechend definiert sein.
Ach ja, ist es denn nicht so das in einem SQLRPGLE Programm keine Binderverzeichnisse bzw externe Prozeduren bzw Serviceprogramme eingebunden werden können ?
sim
-
Wer sagt denn sowas ?
CRTSQLRPGI erlaubt die Angabe OBJTYPE(*PGM/*MODULE), was also das spätere CRTPGM mit Binden auf Service-Programme erlaubt.
Auswahl 15 des PDM macht das automatisch.
Wenn du also sowieso feste Strukturen zum Select definieren musst, und nicht tatsächlich dynamische SQL's benötigst (innerhalb eines Moduls), dann ist embedded SQL die bessere Alternative.
Ausserdem, wie siehts aus mit Update/Insert ?
Similar Threads
-
By Vicky-B in forum NEWSboard Java
Antworten: 17
Letzter Beitrag: 06-05-08, 11:05
-
By pfpk0997 in forum IBM i Hauptforum
Antworten: 4
Letzter Beitrag: 15-11-06, 09:40
-
By falke34 in forum NEWSboard Programmierung
Antworten: 3
Letzter Beitrag: 08-06-05, 14:08
-
By sarge in forum NEWSboard Programmierung
Antworten: 3
Letzter Beitrag: 06-12-04, 08:40
-
By Peter Kosel in forum NEWSboard Programmierung
Antworten: 2
Letzter Beitrag: 21-07-04, 08:17
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks