[NEWSboard IBMi Forum]
Seite 1 von 2 1 2 Letzte

Thema: SQL0811

Hybrid View

  1. #1
    Registriert seit
    Apr 2012
    Beiträge
    360

    SQL0811

    Hallo,

    habe den Sql-Fehler erhalten
    Code:
    Nachrichten-ID . . . . :   SQL0811       Bewertung  . . . . . . :   30         Nachricht . . . :   Ergebnis der Anweisung enthält mehr als eine Zeile.       
    Ursache  . . . . :  Die Ergebnistabelle einer Anweisung SELECT INTO, einer    
      Unterabfrage oder einer Unterauswahl einer Anweisung SET enthält mehr als   
      eine Zeile. Es handelt sich um Fehlerart 1. Bei Fehlerart 1 wurde von einer 
      Anweisung SELECT INTO versucht, mehr als eine Zeile zurückzugeben. Bei      
      Fehlerart 2 wurde durch eine Unterauswahl eines Basisprädikats mehr als eine
      Zeile erstellt. Es ist nur eine Zeile zulässig.                             
    Fehlerbeseitigung:  Die Auswahl so ändern, dass nur eine Ergebniszeile        
      zurückgegeben wird, und die Anforderung wiederholen. Zur Verarbeitung       
      mehrerer Ergebniszeilen müssen die Anweisungen DECLARE CURSOR, OPEN und     
      FETCH verwendet werden. Für eine Unterabfrage können die Prädikate IN,      
      EXISTS, ANY und ALL verwendet werden, um mehrere Ergebniszeilen zu
    Bei den SUM Funktionen habe ich einen Indikator angegeben.

    Meine Vermutung ist es, das der Fehler bei diesem Statement auftritt:
    Code:
                         
    c/exec sql                                          
    C+ SELECT Feld1 INTO :W1feld1  FROM file WHERE .... 
    C+ ....                                             
    c/end-exec
    Fall ich den Fehler abfangen möchte, würde das so funktonieren?
    Code:
    C                   Monitor                         
    c/exec sql                                          
    C+ SELECT Feld1 INTO :W1feld1  FROM file WHERE .... 
    C+ ....                                             
    c/end-exec                                          
    C                   on-Error  *ALL                  
    C                   Endmon                          
    C                   ENDSR
    In welcher Zeile, der Sql-Fehler auftritt, sehe ich aus der Nachricht nicht oder?

    Dank im Voraus

    Gruß

    Tarki

  2. #2
    Registriert seit
    Jan 2001
    Beiträge
    850
    Hallo,

    mit dem Debugger das Programm nach den SQL Statements anhalen
    und das Feld SQLCODE anzeigen. Darin ist der Status
    enthalten.


    Im RPG kann an den Status dann abfragen
    IF SQLCODE =
    Endif


    gruß
    Michael

  3. #3
    Registriert seit
    Apr 2012
    Beiträge
    360
    mein Problem ist es das der spezielle Fall sporadisch vorkommt.
    Falls ich es Teste funktioniert alles so wie es sollte.

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    SQL-Fehler können nicht mit Monitor abgefangen werden, dafür ist der SQLCODE zuständig.

    Dein Problem ist wohl, dass die Where-Klausel ab und zu eben mehr als einen Datensatz liefert.
    In diesem Fall schlägt der SQL fehl und liefert lieber keine Daten.

    Du hast mehrere Möglichkeiten:

    select ....
    fetch first 1 rows only

    Damit wird einfach nur der 1. Datensatz gelesen, egal ob es mehrere gibt.

    Select Min(Feld1) into ...

    nimm halt den kleinsten Wert, alternativ geht natürlich auch MAX/SUM/AVG/...

    Oder prüfe die Daten besser, warum ggf. mehr da ist als du erwartest.
    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
    Apr 2012
    Beiträge
    360
    Aber wie kann vorher schon prüfen/abfangen ob der Sqlfehler auftritt?
    Wie ist da so die Vorgehensweise?

  6. #6
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Zitat Zitat von tarkusch Beitrag anzeigen
    Aber wie kann vorher schon prüfen/abfangen ob der Sqlfehler auftritt?
    Wie ist da so die Vorgehensweise?
    Du prüfst nicht vorher oder hinterher.
    Sofern mehrere Datensätze zurückkommen können und Du z.B. nur wissen willst ob mindestens ein Datensatz vorhanden ist, musst Du, wie Baldur vorgeschlagen hat einfach FETCH 1 ROW ONLY hinzufügen und schon wird entweder kein oder genau 1 Datensatz ausgegeben:

    Code:
     /Free
      Clear isFound;
      Exec SQL   
         Select 1 into :isFound
            From AuftrPos
            where AutrNr = :HstAuftrag
                  and Status < 70
         Fetch First Row Only;
         If SQLCODE < *Zeros and SQLCODE <> -811;
            //Fehler
         ElseIf SQLCODE = 100 or isFound = *Zeros;
            //Kein Satz gefunden
         Else;
            //Satz vorhanden
         Endif;
    Birgitta
    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

  7. #7
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    Kleiner Tipp am Rande:
    Wenn du das SQL Statement öfters aufrufst (vielleicht sogar innerhalb einer Schleife) solltest du lieber einen Cursor verwenden. Auch wenn du nur einen Satz lesen willst.
    Dadurch bleibt ab dem 2ten mal lesen, der ODP vorhanden und muss nicht neu erstellt werden.

    Du könntest es mit einem Select count(*) Into :v1 ... prüfen.
    Wobei das nicht das eigentliche Problem löst.
    Wenn du nur 1 Satz haben willst, musst du feststellen, welche Kriterien zutreffen müssen (WHERE-Klausel). Wenn hin und wieder doch mehrere Sätze vorkommen, dann sind die Kriterien nicht ausreichend und du musst das Konzept neu überdenken.

    Lass ein Monitor für diese Abfrage eingegränzt laufen. Dann siehst du bei welchen Kriterien mehrere Sätze gefunden werden.

    lg Andreas

  8. #8
    Registriert seit
    Apr 2012
    Beiträge
    360
    Ich habe mir die Daten angesehen und es sind defintiv mehrere Sätze zu einem Statement.

    Wie lasse ich eigentlich einen Monitor laufen? Da stehe ich völlig auf dem Schlauch.

    lg
    Tarki

  9. #9
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    Zitat Zitat von tarkusch Beitrag anzeigen
    Wie lasse ich eigentlich einen Monitor laufen? Da stehe ich völlig auf dem Schlauch.
    iSeries Navigator --> Datenbanken --> deine Datenbank --> SQL Performance Monitors
    Rechts-Klick --> Neu --> usw.

    Oder im Green-Screen: STRDBMON

    Wichtig bei beiden ist den Monitor auch wieder manuell zu Beenden. Da er sonst "ewig" läuft.

  10. #10
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Zitat Zitat von andreaspr@aon.at Beitrag anzeigen
    Kleiner Tipp am Rande:
    Wenn du das SQL Statement öfters aufrufst (vielleicht sogar innerhalb einer Schleife) solltest du lieber einen Cursor verwenden. Auch wenn du nur einen Satz lesen willst.
    Dadurch bleibt ab dem 2ten mal lesen, der ODP vorhanden und muss nicht neu erstellt werden.
    Das stimmt so nicht! SELECT ... INTO oder VALUES ... INTO führen im Hintergrund einen DECLARE, OPEN, FETCH und CLOSE aus! Die ODPs bleiben ab dem 2. Mal öffen, sofern sie wiederverwendbar sind.

    Birgitta
    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

  11. #11
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    Zitat Zitat von B.Hauser Beitrag anzeigen
    Das stimmt so nicht! SELECT ... INTO oder VALUES ... INTO führen im Hintergrund einen DECLARE, OPEN, FETCH und CLOSE aus! Die ODPs bleiben ab dem 2. Mal öffen, sofern sie wiederverwendbar sind.
    Das stimmt so auch nicht!
    Ja ich hab das Gerücht mal irgendwo gelesen oder gehört, aber Tatsache ist, dass der ODP jedes mal gelöscht wird.
    Eventuell dass es bei 7.1 so gemacht wird?
    Bis 6.1 wird der ODP jedefalls immer neu erstellt!

  12. #12
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Zitat Zitat von andreaspr@aon.at Beitrag anzeigen
    Das stimmt so auch nicht!
    Ja ich hab das Gerücht mal irgendwo gelesen oder gehört, aber Tatsache ist, dass der ODP jedes mal gelöscht wird.
    Eventuell dass es bei 7.1 so gemacht wird?
    Bis 6.1 wird der ODP jedefalls immer neu erstellt!
    Ich weiß zwar nicht wo Du die Gerüchte gehört hast, bzw. wieso du glaubst, dass der ODP jedesmal gelöscht wird. Der ODP wird nur nach der 1. Ausführung gelöscht (wie auch bei den Cursorn) und bleibt nach der zweiten Ausführung offen (sofern er wiederverwendbar ist) und wird erst geschlossen, wenn die Activierungsgruppe beendet wird, zumindest wenn die Option CLOSQLCSR = *ENDACTGRP ist.

    Hier ein Auszug aus dem Joblog (auf einer Maschine mit V5R4). SELECT ... INTO wird in einer Schleife mehrfach ausgeführt und das Programm sogar zwei Mal aufgerufen:
    Code:
    > call selintox             
       ODP erstellt.                                           
       Blockung für Abfrage.                                     
       Offener Datenpfad (ODP) gelöscht.                       
       Eingebettetes SELECT beendet.                           
       DSPLY  Der Gesamt-Umsatz in 2004 liegt bei 2780.00 Euro 
       ODP erstellt.                                            
       Blockung für Abfrage.                                    
       ODP nicht gelöscht.                                      
       Eingebettetes SELECT beendet.                            
       DSPLY  Der Gesamt-Umsatz in 2005 liegt bei 15276.21 Euro 
       ODP wiederverwendet.                                     
       ODP nicht gelöscht.                                      
       Eingebettetes SELECT beendet.                            
       DSPLY  Der Gesamt-Umsatz in 2006 liegt bei 11409.57 Euro 
    > call selintox                                            
      ODP wiederverwendet.                                     
      ODP nicht gelöscht.                                      
      Eingebettetes SELECT beendet.                            
      DSPLY  Der Gesamt-Umsatz in 2004 liegt bei 2780.00 Euro  
      ODP wiederverwendet.                                     
      ODP nicht gelöscht.                                      
      Eingebettetes SELECT beendet.
    Birgitta
    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

Berechtigungen

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