Anmelden

View Full Version : Heavy standing on the wire. Teil xx



KingofKning
18-01-16, 10:55
Hallo *all,
irgendwie stehe ich auf der Leitung.

Habe folgende Funktion erstellt


CREATE FUNCTION abneh2( PARARTNR dec(3) ) RETURNS
CHAR(10) LANGUAGE SQL READS SQL DATA BEGIN
DECLARE RETURNVAL CHAR ( 10 ) NOT NULL DEFAULT ' ' ;
DECLARE work CHAR ( 100 ) NOT NULL DEFAULT ' ' ;
FOR CSRC1 AS C1 CURSOR
FOR SELECT
case when substr(sdtxt1, 1, 5) = 'Marka' then
substr(sdtxt1, 10, 10) when substr(sdtxt1, 1, 4) = 'Saga' then
substr(sdtxt1, 11, 10) when substr(sdtxt1, 1, 4) = 'EGES' then
substr(sdtxt1, 07, 10) else sdtxt1 end as markt
FROM key01pf
WHERE sdschl = 130 and sdfa = 1
and int(substr(sdind, 12, 3))
= int('002')


Bei dem int(substr( habe ich schon tausend Variationen ausprobiert, bekomme aber immer die Meldung

SELECT/OMIT-Fehler in Feld Cast(Translate(Substr(KEY01PF_1.SDIND,12,3)
*UNNAMED Table) AS Integer), Teildatei KEY01PF.
SELECT-/OMIT-Fehler in Teildatei KEY01PF.
SELECT-/OMIT-Fehler in Teildatei KEY01PF.
Fehler bei Datenumsetzung oder beim Zuordnen von Daten.
Fehler bei benutzerdefinierter Funktion in Teildatei ADR01PF.
Abbruchantwort für Nachricht empfangen.

Kann mir jemand sagen wo der Wald aufhört damit ich den Baum wieder sehe.....


GG

andreaspr@aon.at
18-01-16, 11:23
Steht im Joblog nicht auch nocht die genaue SatzNr. wo der Fehler auftritt?
Hatte auch schon ähnliche Fehler und da lag es daran, dass es einen oder mehrere Sätze gab die einen anderen Inhalt hatten als ich erwartet hätte und da kommt es dann so so einen Fehler.

KingofKning
18-01-16, 11:53
Ich habe mal ein select * darauf gemacht, um dann zu sehen das dort auch Müll drinsteht sprich keine Zahl.

select sdind, int(substr(sdind, 12, 3)) from key01pf
where sdschl = 130
and sdfa = 1
and
int(substr(sdind, 12, 3)) > 0

bricht mir dann auch ab.

Wie kann ich am besten prüfen ob der Inhalt zur Konvertierung Kompatibel ist?

GG

Fuerchau
18-01-16, 11:56
Das Problem bei solchen Konstrukten ist hier der Optimizer.
Durch die Whereklausel nimmt man an, dass diese in genau der vorgegebenen Reihenfolge abgefragt wird so dass der Datenfehler eigentlich nicht auftreten dürfte.
Der Optimizer dreht aber intern die Abfrage häufig um, so dass es zu unerwarteten Datenfehlern kommt.
Leider gibt es hierzu nur 2 Lösungen:
a) dafür sorgen, dass Datenfehler tatsächlich nicht vorkommen
b) die Abfrage auf Zeichen umstellen

and int(substr(sdind, 12, 3)) = int('002')

wird zu

and substr(sdind, 12, 3) = '002'

das ist auf jeden Fall sicherer.
Ist die Herkunft eines Vergleiches ggf. wiederum eine Variable, so musst du diese dann ich Char casten und ggf. formatieren:
- char(myNumVar)
- Digits(myNumVar)
- substr(Digits/char....)

KingofKning
18-01-16, 12:08
Tja,
wenn man denn endlich das Problem verstanden hat, ist der Weg zur Lösung natürlich einfach.

Jetzt ist mein Waldspaziergang beendet.

Danke für die Hinweise.
GG

Fuerchau
18-01-16, 12:20
Wenn du wissen willst, welche Daten fehlerhaft sind gibt's folgende Variante:

where
trim(translate(substr(....), '', '0123456789')) <> ''

Fuerchau
18-01-16, 12:26
Nach der Umstellung von V5R4 auf V6R1 bin ich mit einigen SQL's genau auf dieses Problem gestoßen.
Mit V6R1 wurde der SQL vom Optimizer intern umgestellt, so dass der Datenausschluss der fehlerhaften Sätze nicht mehr funktionierte.
So starben halt einige Programme den Runtime-Tod (machten halt nicht das verlangte) da in den diversen Memoranden für die Umstellung diesbezüglich keine Hinweise gab.
Dies erforderte neben dem Ändern der SQL's ebenso auch eine andere Index-Strategie.
Wenn man solche Konvertierungen im Where anwendet führt das häufiger zum Tablescan als man glaubt.