-
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
-
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
-
mein Problem ist es das der spezielle Fall sporadisch vorkommt.
Falls ich es Teste funktioniert alles so wie es sollte.
-
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.
-
Aber wie kann vorher schon prüfen/abfangen ob der Sqlfehler auftritt?
Wie ist da so die Vorgehensweise?
-
 Zitat von tarkusch
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
-
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
-
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
-
 Zitat von tarkusch
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.
-
 Zitat von andreaspr@aon.at
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
-
 Zitat von B.Hauser
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!
-
 Zitat von andreaspr@aon.at
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
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks