[NEWSboard IBMi Forum]

Thema: UDF

  1. #1
    Registriert seit
    Feb 2003
    Beiträge
    41

    UDF

    Hallo,
    Ich habe eine einfache udf erstellt, die soll immer den nächsten numerischen wert für eine spalte liefern.

    CREATE FUNCTION GETNXTRCN ()
    RETURNS DECIMAL(13, 0) LANGUAGE SQL
    SPECIFIC GETNXTRCN NOT DETERMINISTIC
    READS SQL DATA
    CALLED ON NULL INPUT
    DISALLOW PARALLEL
    SET OPTION ALWBLK = *ALLREAD ,
    ALWCPYDTA = *NO ,
    COMMIT = *NONE ,
    DECRESULT = (31, 31, 00) ,
    DFTRDBCOL = *NONE ,
    DLYPRP = *NO ,
    DYNDFTCOL = *NO ,
    DYNUSRPRF = *USER ,
    SRTSEQ = *HEX
    RETURN ( SELECT MAX( RCN ) + 1 FROM STAT )

    sie funktioniert an sich problemlos, allerdings bei massen-insert auf die datei stat, liefert sie bei jedem satz den gleichen wert. Ich hoffe, ich habe mich klar ausgedrückt.
    bitte keine ratschläge mit autoincrement / trigger usw. - das ist eine Kundendatenbank/kundenanwendung und daran darf nichts geschraubt werden
    vielen dank im voraus
    roman

  2. #2
    Registriert seit
    Jul 2001
    Beiträge
    2.646
    Zitat Zitat von roko Beitrag anzeigen
    sie funktioniert an sich problemlos, allerdings bei massen-insert auf die datei stat, liefert sie bei jedem satz den gleichen wert. Ich hoffe, ich habe mich klar ausgedrückt.
    bitte keine ratschläge mit autoincrement / trigger usw. - das ist eine Kundendatenbank/kundenanwendung und daran darf nichts geschraubt werden
    vielen dank im voraus
    roman
    Puh - aus dem Kopf: das kommt auf Release ,CPU-Multithreading und DB2-Parallelisierung drauf an (evtl. 5722SS1 Opt 27 installiert?). Ausserdem haust Du Dir damit bei Masseninserts auf Multicore-Maschinen evtl. die Performance kaputt. Siehe auch

    iSeries Information Center

    -h

  3. #3
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Ich glaube da fehlt noch was wie Fenced oder so, da Masseninserts ggf. geblockt werden.

    Wenn du schon kein Autoincrement nehmen kannst, gehts auf jeden Fall mit einer "Create Sequence MySequence" und dem daraus folgenden "next value for MySequence".
    Das ist alle mal sicherer und funktioniert auch parallel.
    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

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Und es ist ggf. nicht ein Problem des Masseninserts sondern des Inserts von 2 verschiedenen Jobs.
    In diesem Fall kann auch der selbe Wert zurückgegeben werden.
    Sequence ist da auf jeden Fall sicherer.

    Oder wie Dieter schon des öfteren hingewiesen hat:
    Eine eigene neue Tabelle, in der Sequences verschiedener anderer Tabellen gemeinsam verwaltet werden (benötigt ggf. eigenes Journal).
    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
    Feb 2003
    Beiträge
    41
    vielen dank,
    fenced habe ich bereits erfolglos ausprobiert, kannst du mir ein beispiel für die zweite lösung geben, damit ich nicht im referenzbuch stundenweise suchen muss.
    noch mal vielen dank
    roman

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Genau so, wie oben angegeben.
    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
    Aug 2001
    Beiträge
    2.873
    ... Du meinst mit 2. Lösung die SEQUENCE?

    Wenn Ja ein Sequence Object wird wie folgt erstellt:
    Code:
    CREATE SEQUENCE HSCOMMON10/MYSEQUENCE 
        AS INTEGER START WITH 1 INCREMENT BY 1 
                   NO ORDER NO CYCLE 
                   NO MINVALUE NO MAXVALUE 
                   CACHE 20;
    Am einfachsten geht es mit dem Wizard im iSeries Navigator.

    Bei Sequence Objekten brauchst Du keine UDF, sondern kannst direkt beim Insert oder Update den nächsten Wert anfordern.

    Code:
    Insert MySchema/MyFile
    Values (Next Value For MySequence, .....)
    
    Insert MySchema/MyFile
    as Select Next Value For MySequence, ....
    
    Update MySchema/MyFile
         set Field = Next Value For MySequcence ...
    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  8. #8
    Registriert seit
    Feb 2003
    Beiträge
    41
    vielen dank für das beispiel, so funktioniert es. es ist zwer nicht 'die' lösung, die ich gesucht habe, weil alle anderen programme schreiben sätze native ein und somit wird die sequenz nicht angepasst, ich werde aber für mein job eine temp-sequenz mit startwert = maxwert+1 erstellen (vorher tabelle exclusive sperren) und dann kann ich mein massen-insert machen. mich würde aber die ursprüngliche frage trotzdem interessieren, weil zb. für werte wie 'das datum der letzten bestellung' kann ich keine sequenz verwenden. sollte jemand eine idee habe - her damit.

    noch mal vielen dank für alle antworten und einen schönen tag noch

    roman

  9. #9
    Registriert seit
    Aug 2001
    Beiträge
    2.873
    Du kannst natürlich auch für deine anderen Programme den nächsten Wert in der Sequence über eine SET-Anweisung ermitteln und anschließend in das Original-Datei-Feld umladen.

    Ich habe z.T. solche Ermittlungen in eine eigene Prozedur gepackt, dann muss man die bestehenden Programme nicht auf embedded SQL ändern.

    Beispiel:
    Code:
     /Free
        Exec SQL  Set :MyField = Next Value For MySequence;
        Write MyFileF;
     /End-Free
    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  10. #10
    Registriert seit
    Aug 2001
    Beiträge
    2.873
    ... Was die letzte Zeitmarke angeht, so kann mit der Funktion GENERATE_UNIQUE () ein eindeutiger Wert (auch wenn innerhalb der gleichen Mikrosekunde mehrere Einträge erfolgen) generiert werden, in dem die aktuelle Zeitmarke verschlüsselt ist.

    Mit der Skalaren Funktion TIMESTAMP kann man die Zeitmarke aus diesem generierten eindeutigen Wert ermitteln.

    Allerdings ... das Ergebnis aus GENERATE_UNIQUE() ist im Format "CHAR(13) for BIT DATA".
    In SQL-Tabellen können Spalten mit dieser Formatierung angelegt werden. Für DDS Tabellen müsste das Ergebnis nach Alpha gecastet werden.

    Beispiel:
    Code:
    Select  Generate_Unique(), Timestamp(Generate_Unique())
    From MyFile
    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  11. #11
    Registriert seit
    Feb 2003
    Beiträge
    41
    noch mal vielen dank an alle, die lösung funktioniert jetzt und wird getestet.
    mfg
    roman

Similar Threads

  1. Antworten: 11
    Letzter Beitrag: 18-07-16, 09:49
  2. UDF nicht verwendbar
    By Peder in forum IBM i Hauptforum
    Antworten: 4
    Letzter Beitrag: 06-12-06, 08:15
  3. udf ohne ergebniss
    By ILEMax in forum NEWSboard Programmierung
    Antworten: 25
    Letzter Beitrag: 18-09-06, 13:39
  4. SQL UDF Function ausführung mit Fehler
    By jakarto in forum IBM i Hauptforum
    Antworten: 2
    Letzter Beitrag: 24-07-06, 13:41
  5. SQL UDF Prob mit leeren Feldern
    By HACHIMAN in forum IBM i Hauptforum
    Antworten: 3
    Letzter Beitrag: 22-05-06, 09:48

Berechtigungen

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