[NEWSboard IBMi Forum]
Seite 1 von 2 1 2 Letzte
  1. #1
    Registriert seit
    Dec 2003
    Beiträge
    106

    Question 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;

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    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
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  3. #3
    Registriert seit
    Dec 2003
    Beiträge
    106

    Question

    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) );

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    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.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  5. #5
    Registriert seit
    Dec 2003
    Beiträge
    106
    Zitat 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

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    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
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  7. #7
    Registriert seit
    Dec 2003
    Beiträge
    106

    Cool

    ** 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

  8. #8
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Wofür schlägst du dich denn mit den CLIAPI's rum ?
    Gehts nicht mit Standard-SQL bzw. dynamischem SQL ?
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  9. #9
    Registriert seit
    Dec 2003
    Beiträge
    106
    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*

  10. #10
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    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.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  11. #11
    Registriert seit
    Dec 2003
    Beiträge
    106
    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

  12. #12
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    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 ?
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

Similar Threads

  1. RPG aus Java aufrufen
    By Vicky-B in forum NEWSboard Java
    Antworten: 17
    Letzter Beitrag: 06-05-08, 11:05
  2. ILE RPG aus Stored Procdure aufrufen
    By pfpk0997 in forum IBM i Hauptforum
    Antworten: 4
    Letzter Beitrag: 15-11-06, 09:40
  3. Dialogpgm in Batchverarbeitung aufrufen
    By falke34 in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 08-06-05, 14:08
  4. URL aufrufen
    By sarge in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 06-12-04, 08:40
  5. RPG-Procedur aus CL aufrufen
    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
  •