[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Jul 2007
    Beiträge
    33

    Question Fehler CPD431D: Reduzierung der Gesamtstellenzahl für Operator X'07' nicht zulässig

    Hallo,

    ich bekomme bei einem SQLRPGLE-Programm die folgende Fehlermeldung während das Programm läuft:

    Code:
    Nachrichten-ID . . . . :   CPD431D       Bewertung  . . . . . . :   40        
    Nachrichtenart . . . . :   Diagnose                                           
    Sendedatum . . . . . . :   22.05.24      Sendezeit  . . . . . . :   13:25:26  
                                                                                  
    Nachricht . . . :   Reduzierung der Gesamtstellenzahl für Operator X'07' nicht
      zulässig.                                                                   
    Ursache  . . . . :  Für die Ableitung mit Operator X'07' sind mehr als 31     
      Stellen erforderlich; eine Reduzierung der Gesamtstellenzahl ist aber bei   
      dieser Abfrageanforderung nicht zulässig. Die Ableitung befindet sich im    
      abgeleiteten Eintrag Nummer 3 für das abgeleitete Feld  ACOL00005 im        
      Abfrageformat FORMAT0003. Der erste Operand ist  ACOL00001. Der zweite      
      Operand ist *N. Ist ein Operand *N, ist er das Ergebnis vorheriger          
      Ableitungen, oder für den Operator ist nur ein Operand erforderlich.
    Nach dieser Nachricht kommt zusätzlich auch noch diese Fehlermeldung:
    Code:
    Nachrichten-ID . . . . :   SQL0419       Bewertung  . . . . . . :   30        
    Nachrichtenart . . . . :   Diagnose                                           
    Sendedatum . . . . . . :   22.05.24      Sendezeit  . . . . . . :   13:25:26  
                                                                                  
    Nachricht . . . :   Negative Anzahl an Kommastellen ungültig.                 
    Ursache  . . . . :  Eine dezimale Division führte zu einer negativen Anzahl an
      Kommastellen. Der zur Festlegung der Anzahl der Kommastellen (Scale) für    
      Dezimaldivision verwendete Algorithmus kann in der Themensammlung zu DB2 for
      i SQL Reference in der Kategorie Datenbank im IBM i Information Center unter
      http://www.ibm.com/systems/i/infocenter/ nachgeschlagen werden.             
    Fehlerbeseitigung:  Einen Operanden durch Verwendung der Skalarfunktion FLOAT 
      oder DECFLOAT in Gleitkomma ändern. Dadurch wird das Ergebnis der Division  
      in Gleitkomma geändert. Soll das Ergebnis dezimal sein, Skalarfunktion      
      DECIMAL im Gleitkommaergebnis verwenden. Ist einer der Operanden eine ganze 
      Zahl oder eine kleine ganze Zahl oder eine große ganze Zahl, hat SQL ihn vor
      der Division in dezimal geändert. Mit der Funktion DECIMAL kann die ganze   
      Zahl, die kleine ganze Zahl oder die große ganze Zahl in eine Genauigkeit  
      geändert werden, bei der die Division keine negative Anzahl an Kommastellen
      ergibt. Die Anforderung wiederholen.
    Diese Fehlermeldung kommt bei diesem SQL-Statement zustande:
    Code:
             exec sql
    
                 // Alle Artikel des ODS 1360 und ODS 1361
                 with Shop_ODS_Artikel_kumuliert as (
                   select od.oartnr,
                          sum(case
                              when od.oodsnr = :PiOdsnr_Shp_Stamm then od.oendv
                              else 0
                              end
                          ) as oendv_Stamm,
                          sum(case
                              when od.oodsnr = :PiOdsnr_Shp_Stamm then od.owgpr
                              else 0
                              end
                          ) as owgpr_Stamm,
                          sum(case
                              when od.oodsnr = :PiOdsnr_Shp_Angebot then od.oendv
                              else 0
                              end
                          ) as oendv_Angebot,
                          sum(case
                              when od.oodsnr = :PiOdsnr_Shp_Angebot then od.owgpr
                              else 0
                              end
                          ) as owgpr_Angebot
                     from odssts as od
                    where osa = 'A'
                      and oodsnr in(:PiOdsnr_Shp_Stamm, :PiOdsnr_Shp_Angebot)
                    group by od.oartnr
                    order by od.oartnr
                 ),
    
                 // Jetzt die Preise berechnen
                 Shop_ODS_Artikel as (
                   select gk.oartnr,
    
                    //--- EVP Stamm netto
                          case
                          when af.amwst = 'E' then gk.oendv_Stamm / :PiStBrFE
                          else gk.oendv_Stamm / :PiStBrFV
                          end as shopWgNet_Stamm,
    
                    //--- EVP Stamm brutto
                          gk.oendv_Stamm as shopWgGross_Stamm,
    
                    //--- Ek-Preis Stamm netto
                          gk.owgpr_Stamm as shopEkNet_Stamm,
    
                    //--- Ek-Preis Stamm brutto
                          case
                          when af.amwst = 'E' then gk.owgpr_Stamm * :PiStBrFE
                          else gk.owgpr_Stamm * :PiStBrFV
                          end as shopEkGross_Stamm,
    
                    //--- EVP Angebot netto
                          case
                          when af.amwst = 'E' then gk.oendv_Angebot / :PiStBrFE
                          else gk.oendv_Angebot / :PiStBrFV
                          end as shopWgNet_Angebot,
    
                    //--- EVP Angebot brutto
                          gk.oendv_Angebot as shopWgGross_Angebot
    
                     from Shop_ODS_Artikel_kumuliert as gk
                            join artsfs as af on af.aartnr = gk.oartnr
                    where gk.owgpr_Stamm <> 0 //Es darf keinen Artikel geben,
                                              //bei dem es zwar ein Angebot gibt,
                                              //aber kein Stamm-Preis bei ODS 1360
                    order by gk.oartnr
                 ),
    
                 next10articles as(
                   select kh.ProdId,
    
                          // Gibt es ein Angebot?
                          // Dann diesen Preis als Verkaufspreis,
                          // ansonsten den aus dem Stamm-ODS
                    //--- EVP netto
                          case
                          when shopwgnet_Angebot <> 0 then shopwgnet_Angebot
                          else shopwgnet_Stamm
                          end as shopWgNet,
    
                    //--- EVP brutto
                          case
                          when shopwggross_Angebot <> 0 then shopwggross_Angebot
                          else shopwggross_Stamm
                          end as shopWgGross,
    
                    //--- Streichpreis netto
                          case
                          when shopwgnet_Angebot <> 0 then shopwgnet_Stamm
                          else 0
                          end as ListPriceNet,
    
                    //--- Streichpreis brutto
                          case
                          when shopwggross_Angebot <> 0 then shopwggross_Stamm
                          else 0
                          end as ListPriceGross,
    
                    //--- Einkaufspreis netto
                          shopEkNet_Stamm,
    
                    //--- Einkaufspreis brutto
                          shopEkGross_Stamm
    
                     from kabhds as kh join Shop_ODS_Artikel as ga
                                       on   ga.oartnr = kh.aartnr
                    where kh.kabdnr  = :Shp_kabdnr
                      and kabhds    <> 'L'
               //***
                      and kh.aartnr in (10503, 20324)
               //***
                 )
                 select JSON_OBJECT(
                   'update-prices' value JSON_OBJECT(
                     'entity'     value 'product',
                     'action'     value 'upsert',
                     'payload'    value JSON_ARRAYAGG(
                       JSON_OBJECT(
                         'id'     value trim(ProdId),
    
                         'price'  value JSON_ARRAY(
                           JSON_OBJECT(
                             'currencyId' value 'b7d2554b0ce847cd82f3ac9bd1c0dfca',
                             'net'        value shopWgNet,
                             'gross'      value shopWgGross,
                             'linked'     value 'true' format json,
                             'listPrice'  value JSON_OBJECT(
                               'currencyId' value
                                 'b7d2554b0ce847cd82f3ac9bd1c0dfca',
                               'net'        value ListPriceNet,
                               'gross'      value ListPriceGross,
                               'linked'     value 'true' format json
                             )
                           )
                         ),
    
                         'purchasePrices' value JSON_ARRAY(
                           JSON_OBJECT(
                             'currencyId' value 'b7d2554b0ce847cd82f3ac9bd1c0dfca',
                             'net'        value shopEkNet_Stamm,
                             'gross'      value shopEkGross_Stamm,
                             'linked'     value 'true' format json
                           )
                         )
                       )
                     )
                   )
                 )
                 into :LklData
                 from next10articles;
    Das Programm bereitet (hier exemplarisch nur für 2 Artikel) ein JSON-Objekt für unser Shopware6 vor, welches dann übertragen werden soll.

    Komischerweise funktioniert der gleiche SQL-Befehl im System i Navigator ohne Probleme (dann natürlich mit den entsprechenden Werten, die sonst in den RPG-Variablen stecken), aber sobald er im RPG-Programm eingebunden ist, kommen die beiden Fehlermeldungen.

    Hat jemand eine Idee, was das sein könnte?

    Gruß
    Artur
    (bie-dro KG)

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.307
    Die Anzahl Nachkommastellen bei Zwischenergebnissen werden bei Divisionen auf Max berechnet.
    Im SQL-Handbuch gibts Formeln für die Berechnung der benötigten Genauigkeiten.

    Die Aggregate z.B. ergeben häufig sehr große Felder z.B. 31,2.
    Werden diese nun dividiert muss vorher die max. Genauigkeit ermittelt werden. Dabei wird der Inhalt der Werte nicht geprüft.
    Im Navigator mit Konstanten wird ein Dezimalfeld ermittelt:
    3,2 => dec(2,1)
    12345,567 => dec(8,3)
    usw.

    Helfen kannst du SQL z.B. damit, dass du die Summen selber wieder auf den theoretisch maximalen Inhalt kürzt:
    sum(feld11,2) => sum(31,2)
    Wenn du nun 10000 Zeilen summierst würde 15,2 ja reichen.
    Also kann das Ergebnis der Summe auf dec(sum(xxx), 15, 2) gekürzt werden.

    Divisionen können auch mit dem Kehrwert multipliziert werden.
    Jetzt kommts auf die Genauigkeit an wie viele Nachkomma du im Ergebnis benötigst.
    Bei Multiplikation werden die Ergebniss auf (31, NK1+NK2) erwartet.

    Wenn du im Navigator mit Konstanten testest, caste diese auf die später im Programm verwendeten Hostvariablen, also z.B. dec(1234 , 11 , 2).
    Dann bekommst du da dieselben Fehlermeldungen.
    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
    Jul 2007
    Beiträge
    33

    Thumbs up

    Hallo Baldur,

    danke für deine Antwort. Ich habe mir jetzt so geholfen, dass ich den Divisor zu einer Float-Zahl umwandle und das Ergebnis dann wieder als Dezimal-Zahl wandle. Also so:

    Code:
        ... 
    
        case
        when af.amwst = 'E' then decimal(gk.oendv_Stamm / float(:PiStBrFE), 11, 6)
        else decimal(gk.oendv_Stamm / float(:PiStBrFV), 11, 6)
        end as shopWgNet_Stamm
    
        ...
    Dadurch wird es etwa ab der 4. Nachkommastelle etwas ungenauer, aber das nehme ich in Kauf.

    Aber zumindest kommt dann die Fehlermeldung nicht mehr und ich kann das Programm nutzen.

    Gruß

    Artur

    (bie-dro KG)

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.307
    Da wäre dann ggf. Double noch etwas genauer (17 Stellen).
    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
    Jul 2007
    Beiträge
    33
    Zitat Zitat von Fuerchau Beitrag anzeigen
    Da wäre dann ggf. Double noch etwas genauer (17 Stellen).
    Ich habe es mal im System i Navigator getestet. Konnte aber keinen Unterschied zwischen Float und Double feststellen.

    Bei der Berechnung 4,63 € * 1,19 kommt bei beiden Varianten 5,509699 anstatt 5,5097 heraus. Aber damit kann ich leben.

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.307
    Ja, ich verwechsle Float immer mit REAL.

    Da hilft dann immer noch round(result, 4).
    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.882
    Hast Du eigentlich mal versucht die (Compile/SET OPTION) Option DECRESULT anzupassen, d.h. Größe und Anzahl Dezimal-Positionen für das Ergebnis anzupassen bzw. zu erweitern?
    Birgitta Hauser

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

Similar Threads

  1. UIM-Menü bringt Fehler "Funktionstaste nicht zulässig"
    By RobertSchneider in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 16-07-20, 16:02
  2. SQL Nullwerte nicht zulässig trotz coalesce oder ifnull
    By Progras in forum NEWSboard Programmierung
    Antworten: 11
    Letzter Beitrag: 18-11-16, 11:16
  3. SQL1003 - Verschachtelte /COPY-Anweisungen nicht zulässig
    By cziege in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 10-12-09, 11:48
  4. Embedded SQL in NoMain-Modulen nicht zulässig?
    By JonnyRico in forum NEWSboard Programmierung
    Antworten: 5
    Letzter Beitrag: 02-12-04, 18:14
  5. PLZ 74074 Anstellung als AS400 Operator
    By Moooo in forum NEWSboard Server Job
    Antworten: 0
    Letzter Beitrag: 19-03-02, 11:09

Tags for this Thread

Berechtigungen

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