[NEWSboard IBMi Forum]

Hybrid View

  1. #1
    Registriert seit
    Jun 2001
    Beiträge
    2.044

    Regeln für die Feldgröße

    Hi *all

    bin mal wieder mit einem SQL auf die Nase gefallen.
    Speziell hier:
    QMQRY

    Code:
    SELECT  * from Datei where PER_JJ =  dec(substr(digits(&GRJJMT), 1, 4), 4, 0)  and  PER_M =
    dec(substr(digits(&GRJJMT), 5, 2), 2, 0)

    &GRJJMT ist ein num 8,0 Feld mit JJJJMMTT

    Das hat nicht funktioniert.

    Begründung:
    digits(20121016) = bb20121016 (b = blank)

    Ich frage nun dec(substr(digits(&GRJJMT), 3, 4), 4, 0) bzw.
    dec(substr(digits(&GRJJMT), 7, 2), 2, 0) ab und es geht.

    nun die Frage:
    Gibt es eine Faustformel (oder ein Dokument) wie lang ein Feld durch casten wird?

    Danke
    Robi
    Das Notwendige steht über dem technisch machbaren.
    (klingt komisch, funktioniert aber!)

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.695
    Die Regel ist relativ einfach.
    Die maximal mögliche Ausprägung um den Wert vollständig darzustellen.

    Das Problem ist aber nicht der SQL, da DIGITS immer die Anzahl Stellen nimmt und incl. Vornullen ausgibt.

    Du übergibst die Inhalte an QMQRY wohl falsch.
    Welchen Inhalt hat dein GRJJMT zum Zeitpunkt der Übergabe?

    Außerdem kannst du dir das Auseinandernehmen ja sparen wenn du per Programm direkt die 2 Werte übergibst: &GRJJ und &GRMM.

    SQL erkennt an dieser Stelle einen Ganzzahlwert und nimmt daher Integer (10I) an.
    Die Funktion Digits gibt daher "0020121016" aus.
    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
    Jun 2001
    Beiträge
    2.044
    Hi,
    ich versteh nur Bahnhof.

    Klar könnte ich 2 Felder übergeben. 2 zusätzlich!!
    Die dann aber zum Datum passen müssen, das ich an anderer Stelle brauche

    Die maximal mögliche Ausprägung um den Wert vollständig darzustellen.

    Das Problem ist aber nicht der SQL, da DIGITS immer die Anzahl Stellen nimmt und incl. Vornullen ausgibt.
    maximal möglich von was?

    ich hab im QMQRY ein Sql, u.a. mit dem Inhalt des vorpostes.
    im CL ruf ich STRQMQRY QMQRY(FMD_BASE3) SETVAR((GRJJMT &GRJJMT))

    und &GRJJMT kommt aus einem CMD und ist im CL *char 8 definiert

    selbst wenn ich mir digits(20121016) anzeigen lasse, bekomme ich bb20121016

    Und dafür hätt ich gern 'ein Handbuch' statt versuch und Irrtum


    Robi
    Das Notwendige steht über dem technisch machbaren.
    (klingt komisch, funktioniert aber!)

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.695
    Das ist dann wohl ein Fehler deiner DB2.
    Sind die PTF's aktuell?

    Ich bekomme auf jeden Fall 0020121016 ausgegeben.

    Was die max. Ausprägung angeht, so wird eben die Länge des Feldes für den Cast berücksichtigt.
    Wobei man hier nicht von cast spricht da ja Funktionen verwendet werden.

    SQL Standard:
    cast(value as decimal(8, 0))

    DB2
    decimal(value, 8, 0)

    Nun versucht eben SQL eine Konstante zu analysieren und verwendet den passenden Typ dazu.
    Alle Zahlen ohne Nachkomma werden zu Integer (in ILERPG eben 10I => +/- 2^31-1).
    Mit Nachkomma oder wenn der Wert zu groß ist werden nach Möglickeit Dezimalfelder (bis max 31/63 Stellen) genommen, wenn das nich passt, dann double.

    Komplizierter wirds dann mit CHAR und bei Verwendung im Union-Join.


    PS:
    Da du ja auf jeden Fall einen 10-Stelligen Wert bekommst, kannst du ja die Positionen im substr anpassen.
    Alternativ kannst du auch char(Value) nehmen, solange du eben einen 8-stelligen Wert übergibst, bei "0" gehts dann in die Hose, da char(value) den Wert linksbündig ohne Vornullen ausgibt.
    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
    Nov 2003
    Beiträge
    2.403
    Zitat Zitat von Robi Beitrag anzeigen
    selbst wenn ich mir digits(20121016) anzeigen lasse, bekomme ich bb20121016

    Und dafür hätt ich gern 'ein Handbuch' statt versuch und Irrtum
    Nimm doch dieses Handbuch.

  6. #6
    Registriert seit
    Jun 2001
    Beiträge
    2.044
    Alle Zahlen ohne Nachkomma werden zu Integer (in ILERPG eben 10I => +/- 2^31-1).
    Mit Nachkomma oder wenn der Wert zu groß ist werden nach Möglickeit Dezimalfelder (bis max 31/63 Stellen) genommen, wenn das nich passt, dann double.
    ok, also meistens 10 Stellen
    Test : select digits(5) from datei --> bbbbbbbbb5
    Passt

    2. test select digits(5,2) from datei
    erwartung: b (29) und 52
    ist: 52
    3. test: select digits(feld) from Datei
    mit Feld = Num 5,2 erwartet: bbbbbbb ..152
    ist: 000152 ( hier 0 nicht blank)

    Wo sind die 'regulären' 31 Stellen die ich aus deiner antwort erwartet hätte?

    Danke

    @Pikachu
    bis ich den Wälzer auswendig kann, bin ich in Rente.
    Aber ich kann ja mal anfangen

    Robi
    Das Notwendige steht über dem technisch machbaren.
    (klingt komisch, funktioniert aber!)

  7. #7
    Registriert seit
    Feb 2001
    Beiträge
    20.695
    Also bzgl. der DIGITS-Funktion hast du ggf. ein Anzeigeproblem.
    Die Funktion sollte immer mit Vornullen ausgeben. Warum das bei dir nicht funktioniert kann ich nicht sagen.
    Versuch mal einfach
    char(digits(12345))
    Hierbei ist die Anzeige/Ausgabe erst mal außen vor.

    Im Handbuch steht nichts anderes als ich hier gesagt habe.
    Die 31 Stellen werden nur verwendet, wenn die Konstante auch 31 Ziffern (incl. Nachkomma) hat (ich schrieb ja bis max), also z.B.
    1234567890123456789012345678901
    123456789012345678901,2345678901

    Ansonsten versucht SQL den kleinsten gemeinsamen Nenner zu ermitteln (Stichwort Union).

    Auch bei Berechungen F1 * F2 wird das Ergebnisfeld dann größer, da gibts auch Regeln.
    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

  8. #8
    Registriert seit
    Jun 2001
    Beiträge
    2.044
    ok,
    Größenregel für Digits:

    Ganzzahlen von / bis +/- 2^31-1 : immer 10 Stellig
    Dezimalzahlen: so viele Stellen wie sie haben.
    Rechenergebnisse: immer noch größer --> Testen

    Das mit dem Char ist klar, würde hier auch gehen. Aber da hier, wie überall 'mit den Augen geklaut' wird fällt der nächste, der das Datum als ttmmjjj verarbeitet auf den Bauch

    Danke
    Robi
    Das Notwendige steht über dem technisch machbaren.
    (klingt komisch, funktioniert aber!)

  9. #9
    Registriert seit
    Mar 2002
    Beiträge
    5.365
    ... das Problem sind Literale, die haben keinen expliziten Typ, da muss sich SQL einen auswürfeln (da mag es ein Regelwerk geben, aber warum soll man sich das Leben schwer machen...)

    bei mir jedenfalls:
    select 'a' || digits(20121016) || 'e'
    from sysibm.sysdummy1

    String Expression
    a0020121016e
    ******** End of data ********

    select 'a' || digits(dec(20121016, 8, 0)) || 'e'
    from sysibm.sysdummy1

    String Expression
    a20121016e
    ******** End of data ********

    entweder ist dein Feld dec(10, 0) oder das DB2/400 hat einen Schuss.

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  10. #10
    Registriert seit
    Jun 2001
    Beiträge
    2.044
    Moin,

    beide Bsp bei mir genau so !
    Auch das erste mit der 0 !

    aber

    Ich hatte eine Num. Variable mit jjjmmtt und wollte das Jahr bzw den Monat extrahieren.

    also aus numerisch alpa machen
    digits(&GRJJMT)

    daraus (z.B. den Monat) extrahiereneinen
    subsstr(digits(&GRJJMT), 5, 2)

    und das wieder 2 Stellig numerisch machen um es mit dem Periodenmonat zu vergleichen

    dec(subsstr(digits(&GRJJMT), 5, 2), 2, 0)

    Nur das das Ergebniss meistens 12 war, da
    digits(&GRJJMT) = digits(20121016) = 'bb20121016)


    Nun weis ich, es geht auch ein
    substr(&GRJJMT, 5, 2) = substr(20121016, 5, 2)

    da SQL gar nicht weis, das 20121016 numerisch ist

    Robi
    Das Notwendige steht über dem technisch machbaren.
    (klingt komisch, funktioniert aber!)

  11. #11
    Registriert seit
    Feb 2001
    Beiträge
    20.695
    Aber hier hast du bzgl. des "abkupferns" das selbe Problem.
    Hier wird ein Autocast mittels CHAR durchgeführt.
    Übergibst du also mal TTMMJJJJ fehlt dir wieder die Vornull.

    Und SQL stellt natürlich fest, dass du keinen String übergeben hast sondern einen numerischen Wert.
    Dieser wird dann erst in Integer gewandelt und dann mittles cast in Char.

    Wenn du es genau machen willst müsstest du auch einen String übergeben:

    SETVAR((GRJJMT ('''' *cat &GRJJMT *cat '''')))
    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. V5R1 Bug ?
    By SE in forum IBM i Hauptforum
    Antworten: 10
    Letzter Beitrag: 28-02-02, 12:40

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •