[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Mar 2004
    Beiträge
    33

    sql update (Verständnis-)Problem

    Hallo,

    ein Artikel hat mehrere verschiedene Gewichtungswerte abhängig vom Typ.
    Die Tabellenstruktur sieht wie folgt aus
    Artnr | Jahr | Typ | Wert

    Der Schlüssel ist Artnr, Jahr, Typ

    Ich möchte numerische Werte innerhalb eines Jahres von einem Typ in den Nächsten übertragen mit einer Veränderung (teilweise Addition, teilweise Subtraktion).

    Mein erster Versuch des Updates vom Typ 2 in den Typ N sah wie folgt aus:
    Code:
    update table as a
    set a.Wert=(
                 (select b.Wert from table as b
                  where b.Jahr = 2020 and b.Typ = '2'  and
                        a.Jahr =  b.Jahr and a.Artnr = b.Artnr
                 )+1.8
               )
    where a.Jahr = 2020 and a.Typ = 'N'
    Dieses Update hat aber nicht immer fuktioniert und ist manchmal in einen Fehler
    Code:
    Nullwerte für Spalte oder Variable WERT nicht zulässig.
    gelaufen.

    Nach mehreren Versuchen habe ich nun diesen Update zusammengebaut:
    Code:
    update table as a
    set a.Wert=(
                 (select b.Wert from table as b
                  where b.Jahr = 2020 and b.Typ = '2'  and
                        a.Jahr =  b.Jahr and a.Artnr = b.Artnr
                 )+1.8
               )
    where a.Jahr = 2020 and a.Typ = 'N' and
          exists(select b.Wert 
                 from table as b
                 where b.Jahr = 2020 and b.Typ = '2'  and
                       a.Jahr = b.Jahr and a.Artnr = b.Artnr
                )
    Hier meine Fragen:
    Ist der doppelt verwendete Alias "b" korrekt?
    Ist durch die Verknüpfung im Subselect der SET-Klausel nicht gewährleistet, dass a und b eindeutig verbunden sind und daraus folgend Variante 1 ausreichend?
    Wenn ich den Subselect alleine ausführe kommen zwar Werte wie 0,00 aber keine NULL Werte. Daraus habe ich geschlossen, dass nur zulässige Werte geschrieben werden. Woher kommen dann die Nullwerte?

    Grüße

    Marc

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Für den Subselect kannst du eine Klammerstufe weglassen, da nur der Select-Ausdruck in Klammern zu setzen ist.
    Ein Alias betrifft nur den jeweiligen Kontext, in deinem Fall nur die Subselects. Der eine Subselect hat mit dem Anderen nichts zu tun.

    Nun zur Reihenfolge:

    Die Where-Klausel des Hauptselects schließt nur die Zeilen ein, die für den Update relevant sein sollen.
    Der 1. Subselect hat aber eine andere Beziehung als der Hauptwhere und somit kann es eben vorkommen, das zu dem zu ändernden Satz das Pendant gar nicht vorhanden ist. Also nicht für jeden Typ-N-Satz gibt es auch einen Typ-2-Satz.
    Und genau dann kommt es zum NULL-Ergebnis.

    Der 2. Subselect (exists) stellt nun sicher, das für jeden zu ändernden Satz auch ein Pendant als Quelle vorhanden ist und somit NULL-Werte ausgeschlossen werden (solange nicht NULL auf Feldebene zulässig wäre).

    Du könntest den 2. Subselect weglassen, wenn du den 1. in "coalesce((select ...) + 1.8, a.Wert)" änderst. Dies führt aber u.U. zu mehr unnötigen Änderungen, da ja der Satz ohne pendant mit sich selbst überschrieben wird.

    Zu guter Letzt, betrachte mal deinen Inner-Where:
    where b.Jahr = 2020 and b.Typ = '2' and
    a.Jahr = b.Jahr
    and a.Artnr = b.Artnr

    Da du im Hauptwhere bereits auf 2020 einschränkst, kann die zusätzliche Einschränkung im Subselect doch entfallen.

    Generell gilt beim Subselect:
    Ist kein Ergebnis zu finden, wird NULL gemeldet, also genau das selbe wie auch beim Left Join.
    Einen "Inner-Join"-Subselect gibt es nicht.
    Es gibt daher auch immer mal wieder viele Joblog-Hinweise, dass NULL-Indikatoren fehlen:

    select count(*) into : MyCount
    from table
    where ....

    Da hierfür kein Cursor verwendet wird, betrachtet SQL dies wie einen Subselect und liefert NULL falls die Whereklausel nichts findet.
    Machst du das selbe per Cursor (wie z.B. via STRSQL), bekommst du ganz normal 0 geliefert.
    Besser wäre dann hier:

    select coalesce(count(*), 0) into : MyCount
    from table
    where ....

    oder eben einen NULL-Anzeiger (nicht zu vergessen, den NULL-Anzeiger abzufragen oder das Zielfeld vorher zu löschen, da es im NULL-Fall den vorherigen Wert behält).
    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
    Mar 2004
    Beiträge
    33
    Hallo,

    sorry für die späte Antwort. Ich hatte Schwierigkeiten mich im Forum anzumelden und nach vielen erfolglosen Versuchen es heute erst wieder probiert.
    Vielen Dank für die ausführliche Antwort. Ich muss das ganze noch ein paar Mal testen/üben, bis es auch ganz verinnerlicht ist. Jedenfalls habe ich jetzt eine sehr gute Anleitung zum nachschlagen.

    Grüße

    Marc

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Das Forum war leider eine Weile "out of order". Also nicht nur du konntest dich nicht anmelden.
    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. Nullwerte Problem bei UPDATE
    By sonicreducer in forum NEWSboard Programmierung
    Antworten: 11
    Letzter Beitrag: 12-04-16, 12:52
  2. Update RDi 9.1.1.1
    By andreaspr@aon.at in forum IBM i Hauptforum
    Antworten: 6
    Letzter Beitrag: 01-12-15, 11:28
  3. Windows Problem nach Update von iAccess [gelöst]
    By JanItor in forum IBM i Hauptforum
    Antworten: 10
    Letzter Beitrag: 11-02-15, 16:13
  4. Left join Verständnis Frage
    By KingofKning in forum NEWSboard Programmierung
    Antworten: 10
    Letzter Beitrag: 17-11-14, 15:52
  5. SQL update
    By Joe in forum IBM i Hauptforum
    Antworten: 4
    Letzter Beitrag: 15-04-03, 16:06

Tags for this Thread

Berechtigungen

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