[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Nov 2016
    Beiträge
    4

    SQL Nullwerte nicht zulässig trotz coalesce oder ifnull

    Hallo,

    ich komme nicht weiter. Dieses SQL Statement liefert mir die Fehlermeldung 'Nullwerte für Spalte oder Variable TEAT05 nicht zulässig. Wenn ich eine bestimmte soid4 auswähle, die einen Wert enthält, dann funktioniert es. Was mache ich falsch?

    update tst01pf t
    set t.teat05 = (select ifnull(s.soeipr, 0)
    from son01pf s
    where t.tetenr = s.soid4
    and s.sofa =01
    and s.sodtbi >= 161231
    and s.soeipr <> 0
    and s.soeipr is not null
    and s.soid1=30600
    and s.sosts = 0)
    where t.tefa = 10 and tetenr=11

    Gruß

    Progras

  2. #2
    Registriert seit
    Mar 2002
    Beiträge
    5.286
    ... klemmt, wenn keine Zeile zurück kommt!

    statt select ifnull(...) from ...
    set (coalesce((select ... from...), 0)

    außerdem geht das auch schief, wenn mehr als eine Zeile zurück kommt

    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/

  3. #3
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    IFNULL ersetzt dir nur den Wert für eine Spalte einer VORHANDENEN Zeile.
    Wenn der Datensatz nicht existiert, kann auch kein Ersatzwert gesetzt werden.

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    NULLIF(Feld, 0) entspricht: case when feld =0 then null else feld end
    COALESCE(Feld, 0) entspricht: case when feld is null then 0 else feld end

    Da dein Zielfeld aber NULL nicht erlaubt (siehe Fehlermeldung) darfst du nicht NULL im Ergabnis haben.
    Also wäre Dieters Lösung "select coalesce(feld, 0) from ... where ..." die Richtige.
    Allerdings wird trotzdem NULL geliefert, wenn die Where-Klausel nicht fündig wird.
    Also "coalesce((select feld from ... where ...), 0)" ist dann fast perfekt.
    Um auszuschließen, dass mehr als 1 Zeile kommt, falls die Daten es zulassen, kann man noch ergänzen:
    coalesce((select feld from ... where ... fetch first 1 rows only), 0)
    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 2016
    Beiträge
    4
    Super, danke Fuerchau und BenderD, das hat mir beides gut weitergeholfen. Die Abfrage funktioniert nun.

    Aber wie Fuerchau schon beschrieben hat, wird 0 geliefert, wenn nichts gefunden wird (Auch mit 'fetch first 1 rows only'). Wie kann ich es vermeiden, dass das Feld teat05 überschrieben wird, wenn das Select Ergebnis 0 liefert?

    Zum Verständnis meiner Abfrage: Ich möchte, abhängig von der Artikelnummer, die Preise in son01pf der Firma 01 in die tst1pf der Firma 10 schreiben. Das sind ca. 700 Preise. Aber das SQL updated das Feld teat05 in allen 8000 Zeilen der Firma 10 in der tst01pf.

    update tst01pf t
    set t.teat05= coalesce((select s.soeipr
    from son01pf s
    where t.tetenr = s.soid4
    and s.sofa =01
    and s.sodtbi >= 161231
    and s.soeipr <> 0
    and s.soeipr is not null
    and s.soid1=30600
    and t.tefa = 10
    and s.sosts = 0
    fetch first 1 rows only), 0)
    where t.tefa = 10

    Gruß

    Progras

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    coalesce((select nullif(soeipr, 0)...), teat05)

    Wenn "soeipr = 0" dann nimm NULL, wenn das Ergebnis des Selects NULL, dann nimm den Ursprung.
    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.869
    Die korrekte Syntax für den Update einer Tabelle auf Basis einer zweiten Tabelle sieht wie folgt aus:

    Code:
    Update YourTable a
       set YourColumn = (Select Distinct YourNextColumn
                           From NextTable b
                           Where     a.Key1 = b.Key1
                                 and a.Key2 = b.Key2
                                 ...
                                 and a.KeyN = b.KeyN)
       Where Exists (Select * 
                        from  NextTable c
                        Where     a.Key1 = c.Key1
                              and a.Key2 = c.Key2
                              ...
                              and a.KeyN = c.KeyN);
    Dadurch wird sichergestellt, dass für jeden Datensatz aus der ersten Datei genau ein Datensatz aus der zweiten Datei gefunden wird. Fehlen Datensätze in der ersten Datei oder der zweiten Datei, werden diese elimiert bzw. erfolgt kein Update auf den entsprechenden Satz.

    Damit ist eine explizite Konvertierung von NULL-Werten mittels COALESCE oder IFNULL nicht erforderlich.

    Doppelte Datensätze werden ebenfalls vermieden.

    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 2001
    Beiträge
    20.207
    Der "Distinct" (= Eindeutig) sorgt nur dafür, dass es keine doppelten Werte gibt.
    Er verhindert nicht, dass mehr als 1 Zeile zurückkommt wenn es mehrere unterschiedliche Werte gibt.
    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
    Aug 2006
    Beiträge
    2.074
    Zitat Zitat von Progras Beitrag anzeigen
    update tst01pf t
    set t.teat05= coalesce((select s.soeipr
    from son01pf s
    where t.tetenr = s.soid4
    and s.sofa =01
    and s.sodtbi >= 161231
    and s.soeipr <> 0
    and s.soeipr is not null
    and s.soid1=30600
    and t.tefa = 10
    and s.sosts = 0
    fetch first 1 rows only), 0)
    where t.tefa = 10
    Progras
    Da sieht mir schwer nach einem ERP System aus Koblenz aus ;-)

    GG 4943

  10. #10
    Registriert seit
    Mar 2002
    Beiträge
    5.286
    Zitat Zitat von Progras Beitrag anzeigen
    Super, danke Fuerchau und BenderD, das hat mir beides gut weitergeholfen. Die Abfrage funktioniert nun.

    Aber wie Fuerchau schon beschrieben hat, wird 0 geliefert, wenn nichts gefunden wird (Auch mit 'fetch first 1 rows only'). Wie kann ich es vermeiden, dass das Feld teat05 überschrieben wird, wenn das Select Ergebnis 0 liefert?

    Zum Verständnis meiner Abfrage: Ich möchte, abhängig von der Artikelnummer, die Preise in son01pf der Firma 01 in die tst1pf der Firma 10 schreiben. Das sind ca. 700 Preise. Aber das SQL updated das Feld teat05 in allen 8000 Zeilen der Firma 10 in der tst01pf.

    update tst01pf t
    set t.teat05= coalesce((select s.soeipr
    from son01pf s
    where t.tetenr = s.soid4
    and s.sofa =01
    and s.sodtbi >= 161231
    and s.soeipr <> 0
    and s.soeipr is not null
    and s.soid1=30600
    and t.tefa = 10
    and s.sosts = 0
    fetch first 1 rows only), 0)
    where t.tefa = 10

    Gruß

    Progras
    ... das lässt sich auch einfach so heilen:
    update tst01pf t
    set t.teat05= coalesce((select s.soeipr
    from son01pf s
    where t.tetenr = s.soid4
    and s.sofa =01
    and s.sodtbi >= 161231
    and s.soeipr <> 0
    and s.soeipr is not null
    and s.soid1=30600
    and t.tefa = 10
    and s.sosts = 0
    fetch first 1 rows only), t.teat05)
    where t.tefa = 10

    wobei der fetch first möglicherweise nicht das ist, was man haben will, der holt nämlich der erstbesten, den er gerade findet. Da sollte man schon mal prüfen, ob es da eine ausreichende Schlüsselbeziehung gibt, oder eher mit min oder select max(s.soeipr) oder min(...) arbeiten.

    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/

  11. #11
    Registriert seit
    Nov 2016
    Beiträge
    4
    Zitat Zitat von Fuerchau Beitrag anzeigen
    coalesce((select nullif(soeipr, 0)...), teat05)

    Wenn "soeipr = 0" dann nimm NULL, wenn das Ergebnis des Selects NULL, dann nimm den Ursprung.
    Mit dieser Erweiterung hat es dann letztendlich funktioniert. Die Verion von BenderD habe ich nicht getestet, klingt aber plausibel. Ist noch vereinfacht.

    @Birgitta: Dieses Update hat wieder zur gleichen Meldung mit den Nullwerten geführt. Konnte es aber für ein anderes Problem gut gebrauchen.

  12. #12
    Registriert seit
    Nov 2016
    Beiträge
    4
    Zitat Zitat von KingofKning Beitrag anzeigen
    Da sieht mir schwer nach einem ERP System aus Koblenz aus ;-)

    GG 4943
    Kann ich nichts dazu sagen. Bin Azubi und dies war ein Problem in der Schule, welches ein Mitschüler mitgebracht hatte.

Similar Threads

  1. Update (rewrite und/oder write) wird nicht aktiv
    By woy in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 26-03-15, 09:49
  2. CPF5125 oder warum reagiert er nicht auf close
    By Robi in forum NEWSboard Programmierung
    Antworten: 6
    Letzter Beitrag: 04-03-14, 15:49
  3. FTP Append kann Datei nicht öffnen oder erstellen
    By msost in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 04-12-13, 16:39
  4. command ag: Trotz ERP-Flaute 13 Prozent mehr Umsatz
    By RM Haaßengier in forum Archiv NEWSblibs
    Antworten: 0
    Letzter Beitrag: 10-07-02, 16:20
  5. Antworten: 4
    Letzter Beitrag: 13-08-01, 11:22

Berechtigungen

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