PDA

View Full Version : Embedded SQL - keine Daten bei 2. Aufruf



Seiten : 1 [2]

BenderD
21-05-08, 09:05
es gilt immer noch:
- SQLCODE abfragen
- Joblog mit allen Details ansehen
- letzteres auch mit STRDBG, was SQL ausführlicher protokollieren lässt

interaktives SQL zeigt für Nullwerte automatisch Ersatzwerte an, beim insert geht das schief, wenn die Zieltabelle keine Nullwerte zulässt.
entweder Zieltabelle per SQL erstellen lassen:
create table as (select....) with no data usw.
oder im select die Nullwerte ersetzen
select a.xxx, coalesce(b.mynum, 0), coalesce(b.myalf, ' ')...
from mytable a left outer join anotherTable b on ...

D*B



Hallo Birgitta,

vielen Dank für die Antworten :-)

Habe den Fehler nun gefunden: Es lag daran, dass ich ein alphanumerisches Feld folgendermaßen in der Where-Bedingung abgefragt habe:

...
And Case When :igebart <> 0 Then :igebart Else vsgeba end = vsgeba

anstatt:
...
And Case When :igebart <> ' ' Then :igebart Else vsgeba end = vsgeba

Beim ersten Aufruf hat es immer funktioniert. Ab dem 2. jedoch nicht mehr. Wahrscheinlich wurde durch das erste exfmt das Feld mit *blank initialisiert und war somit unterschiedlich zu 0, wodurch die Where-Anweisung verhunzt war.
Nach dieser "klitzekleinen" Änderung funktioniert es.
Was ich allerdings immernoch nicht so ganz verstehe ist, warum es auch nach einem Beenden und Neuaufruf des Programms nicht wieder funktioniert hat ?!?

Nun habe ich allerdings noch einen weiteren Fehler gefunden :-(

Ich verknüpfe in meiner Select-Abfrage insgesamt 17 Files; eine davon 2 mal (Kunde und Verband).
Die Joins sind allesamt Left Outer Joins.
Ich habe in unserer Statistik (Aliasname: Statistik) TNr mit Suffix, die nicht im Teilestamm (Dateiname: MITEM) hinterlegt sind.
Über strsql funktioniert dies auch; in embedded SQL allerdings nicht.
Dort werden die TNr, die sich nicht im Teilestamm befinden auch nicht in meine Ausgabedatei geschrieben.

Woran kann dies liegen ??

Nachfolgend die SQL-Abfrage:

Exec SQL
Insert into VOGIO/EXVT0547
Select vsman, vsvbnr, a.ana1, a.ana2, a.acoi, a.apla, a.aort, a.astr,
vskdnr, b.ana1, b.ana2, b.acoi, b.apla, b.aort, b.astr,
vskdgr, c.tabbez, kdslbr, d.tabbez, vsvtr, e.tabbez,

vstnr, imdsc, imsts, vspgrg, f.tabbez, vsmagr, g.tabbez,
mi1v22, h.tabbez, vsmark, i.tabbez, vsmrze, j.tabbez,
vsprgr, k.tabbez, vsprug, l.tabbez, vsgebi, m.tabbez,
vsgeba, n.tabbez, mi1v19, o.tabbez,

vvimg3, vvimg2, vvimg1, vvimg0,
vviwg3, vviwg2, vviwg1, vviwg0

From VOGIO/Statistik Left Outer Join DCWD/AADRNU a
on vsvbnr = a.anum

Left Outer Join DCWD/AADRNU b
on vskdnr = b.anum

Left Outer Join VOGIO/KUNDST00
on vskdnr = kdnr

Left Outer Join VOGIO/V#TAK100 c
on vskdgr = c.tabinn

Left Outer Join VOGIO/V#TABR00 d
on kdslbr = d.tabinn

Left Outer Join VOGIO/V#TAVT00 e
on vsvtr = e.tabinn

Left Outer Join SIM400MFG/FKITMSTR
on vstnr = impn

Left Outer Join VOGIO/V#TAPU00 l
on vsprug = l.tabind

Left Outer Join VOGIO/V#TAGB00 m
on vsgebi = m.tabind

Left Outer Join VOGIO/V#TATH00 n
on vsgeba = n.tabind

Left Outer Join VOGIO/V#TALI00 o
on mi1v19 = o.tabinz

Where
Case When :ikdgr <> 0 Then :ikdgr Else vskdgr end = vskdgr
And Case When :ikdbr <> 0 Then :ikdbr Else kdslbr end = kdslbr
And Case When :ikdland <> ' ' Then :ikdland Else vsbla end = vsbla
And Case When :ivtr <> 0 Then :ivtr Else vsvtr end = vsvtr
And Case When :iverb <> 0 Then :iverb Else vsvbnr end = vsvbnr
And Case When :ikdnr <> 0 Then :ikdnr Else vskdnr end = vskdnr

And Case When :imagr <> ' ' Then :imagr Else vsmagr end
= vsmagr
And Case When :imhptgr <> ' ' Then :imhptgr Else mi1v22 end
= mi1v22
And Case When :imarkind <> ' ' Then :imarkind Else vsmark end
= vsmark
And Case When :iwg <> ' ' Then :iwg Else vsmrze end = vsmrze
And Case When :iprodgr <> ' ' Then :iprodgr Else vsprgr end
= vsprgr
And Case When :iprodugr <> ' ' Then :iprodugr Else vsprug end
= vsprug
And Case When :igebgr <> ' ' Then :igebgr Else vsgebi end = vsgebi
And Case When :igebart <> ' ' Then :igebart Else vsgeba end
= vsgeba
And Case When :iuland <> ' ' Then :iuland Else mi1v19 end = mi1v19
And Case When :ipreisgr <> ' ' Then :ipreisgr Else vspgrg end
= vspgrg
And Case When :itnr <> ' ' Then :itnr Else vstnr end = vstnr
And Case When :istatus <> ' ' Then :istatus Else imsts end
= imsts;

Mit folgendem Test über strsql bekomme ich das gewünschte Ergebnis:

select vskdnr, vstnr, mi1mnr, mi1mlb, mi1v22, a.tabbez, mi1v19,
b.tabbez
from vogio/v#vsta00
left outer join dcwd/mitem on vstnr = mi1mnr
left outer join vogio/v#tamh00 a on mi1v22 = a.tabind
left outer join vogio/v#tali00 b on mi1v19 = b.tabinz
where vskdnr = 3215 <--- bei dieser KdNr. gibt es etliche Suffix-TNr, die nun angezeigt werden

Tobse77
21-05-08, 10:00
Hallo Dieter,

Danke für die Antworten und die Geduld :-)

- SQLCODE = 0
- Joblog unter strdbg:

2 > STRDBG PGM(VT0547) UPDPROD(*YES)
2 > call vt0547
Objekt EXVT0547 in VOGIO Art *FILE wurde gelöscht.
Datei EXVT0547 in Bibliothek VOGIO erstellt.
Teildatei EXVT0547 zu Datei EXVT0547 in VOGIO hinzugefügt.
Abfrageoptionsdatei kann nicht abgerufen werden.
CONNECT für relationale Datenbank S6599E0C abgeschlossen.
Aktuelle Verbindung besteht zur relationalen Datenbank S6599E0C.
Löschen von STATISTIK in VOGIO beendet.
Aliasname STATISTIK in VOGIO erstellt.
Abfrageoptionsdatei kann nicht abgerufen werden.
****: Debug-Nachrichten des Optimierungsprogramms für Abfrage werden
gestartet.
Abfrageoptionsdatei kann nicht abgerufen werden.
Abfrageoptionsdatei kann nicht abgerufen werden.
Temporäre Datei für Datei MITEM erstellt.
Der Zugriffsplan der Abfrage wurde erneut erstellt.
Auswahlfelder anderen Attributen zugeordnet.
Alle Zugriffspfade wurden für Datei V#VSTA00 berücksichtigt.
Zusätzliche Ursachencodes für Zugriffspfad verwendet.
Alle Zugriffspfade wurden für Datei AADRNU berücksichtigt.
Alle Zugriffspfade wurden für Datei AADRNU berücksichtigt.
Alle Zugriffspfade wurden für Datei KUNDST00 berücksichtigt.
Alle Zugriffspfade wurden für Datei FKITMSTR berücksichtigt.
Zugriffspfad für Datei AADRNU erstellt.
Zugriffspfad für Datei AADRNU erstellt.
Zugriffspfad für Datei KUNDST00 erstellt.
Zugriffspfad für Datei FKITMSTR erstellt.
Zugriffspfad für Datei *QUERY0001 erstellt.
Datei V#VSTA00 in Verknüpfungsposition 1 verarbeitet.
Datei AADRNU in Verknüpfungsposition 2 verarbeitet.
Datei AADRNU in Verknüpfungsposition 3 verarbeitet.
Datei KUNDST00 in Verknüpfungsposition 4 verarbeitet.
Datei V#TAK100 in Verknüpfungsposition 5 verarbeitet.
Datei V#TABR00 in Verknüpfungsposition 6 verarbeitet.
Datei V#TAVT00 in Verknüpfungsposition 7 verarbeitet.
Datei FKITMSTR in Verknüpfungsposition 8 verarbeitet.
Datei *QUERY0001 in Verknüpfungsposition 9 verarbeitet.
Datei V#TAP100 in Verknüpfungsposition 10 verarbeitet.
Datei V#TAMG00 in Verknüpfungsposition 11 verarbeitet.
Datei V#TAMH00 in Verknüpfungsposition 12 verarbeitet.
Datei V#TAMA00 in Verknüpfungsposition 13 verarbeitet.
Datei V#TAWG00 in Verknüpfungsposition 14 verarbeitet.
Datei V#TAPG00 in Verknüpfungsposition 15 verarbeitet.
Datei V#TAPU00 in Verknüpfungsposition 16 verarbeitet.
Datei V#TAGB00 in Verknüpfungsposition 17 verarbeitet.
Datei V#TATH00 in Verknüpfungsposition 18 verarbeitet.
Datei V#TALI00 in Verknüpfungsposition 19 verarbeitet.
Abfrageoptionsdatei kann nicht abgerufen werden.
****: Debug-Nachrichten für Abfrage werden beendet.
ODP erstellt.
Blockung für Abfrage.
Abfrageoptionsdatei kann nicht abgerufen werden.
****: Debug-Nachrichten des Optimierungsprogramms für Abfrage werden
gestartet.
Abfrageoptionsdatei kann nicht abgerufen werden.
****: Debug-Nachrichten des Optimierungsprogramms für Abfrage werden
gestartet.
Der Zugriffsplan der Abfrage wurde erneut erstellt.
Zugriff nach Eingangsfolge für Datei EXVT0547 verwendet.
Abfrageoptionsdatei kann nicht abgerufen werden.
****: Debug-Nachrichten für Abfrage werden beendet.
ODP erstellt.
Datenumsetzung für Anweisung INSERT oder UPDATE erforderlich.
ODP nicht gelöscht.
ODP nicht gelöscht.
6507 Zeilen in EXVT0547 in VOGIO eingefügt.
2>> enddbg

Die Zieldatei EXVT0547 ist in jedem Feld mit Schlüsselwort ALWNULL definiert. Genügt dies oder muss ich trotzdem mit der COALESCE-Funktion arbeiten?



es gilt immer noch:
- SQLCODE abfragen
- Joblog mit allen Details ansehen
- letzteres auch mit STRDBG, was SQL ausführlicher protokollieren lässt

interaktives SQL zeigt für Nullwerte automatisch Ersatzwerte an, beim insert geht das schief, wenn die Zieltabelle keine Nullwerte zulässt.
entweder Zieltabelle per SQL erstellen lassen:
create table as (select....) with no data usw.
oder im select die Nullwerte ersetzen
select a.xxx, coalesce(b.mynum, 0), coalesce(b.myalf, ' ')...
from mytable a left outer join anotherTable b on ...

D*B

BenderD
21-05-08, 10:51
- erstmal siehst du im Joblog, dass da 6507 Sätze eingefügt wurden
- davor ist nochwas mit Datenumsetzung, was du nochmal prüfen solltest
- wenn dein interaktives Statement da was anderes liefert, dann musst du das Stück für Stück analysieren.
- die Meldungen Zugriffspfad erstellt solltest du nochmal genauer ansehen, inklusive der vorhergehenden, die die jeweilige Datei betreffen, da wirst du das finden, was hier Zeit braucht und wie man es schneller machen kann (und oft logische Fehler in der Verknüpfung), den ganzen open close Zinnober, den kannst du getrost vergessen, das ist Pillepalle im Vergleich zu Zugriffspfad Aufbau!!!!!!!

BTW: deinen ursprünglichen Fehler hättest du im Joblog bei dieser Vorgehensweise in 10 Minuten gefunden!!!
Mit open close hat der wohl nix zu tun, sondern mit dem jeweiligen Inhalt von Programmvariablen (SQL ist steng typgebunden, RPG eine Huddelprogrammiersprache, die im Zweifel jeden Schlunz in Variablen reinfummeln lässt). Beim Beenden des Jobs und Neuaufruf wird frisch initialisiert angefangen, bei erneutem Aufruf im selben Job bleibt ein ILE Modul aktiviert (ausser ACTGRP *NEW) - das ist vergleichbar zum verlassen OPM Programm ohne LR

D*B

Tobse77
21-05-08, 11:37
Danke für die Tipps. Da ich lediglich die Vorteile von RPGIV gegenüber RPG400 nutze, aber nicht im ILE-Konzept programmiere, bin ich hier sehr unerfahren.

- Die eingefügten Sätze sollten eigentlich 6532 sein, aber die Suffix-TNr lässt er ja weg.
- Das mit der Datenumsetzung hat Ursachencode 8 (Die Zieltabelle der Anw. INSERT ist keine SQL-Tabelle) <- stimmt; ist DDS!!
- bzgl. der Meldungen mit dem Zugriffspfad habe ich gesehen, dass ein temp. Zugriffspfad erstellt wurde und dabei kein "Parallelismus" verwendet wurde ... ich schätze mal, das ist gut so :-)

Die interaktive SQL-Anweisung habe ich nun auch einmal im Debug-Modus laufen lassen:
> strdbg
> strsql
Aktuelle Verbindung besteht zur relationalen Datenbank S6599E0C.
Abfrageoptionsdatei kann nicht abgerufen werden.
Abfrageoptionsdatei kann nicht abgerufen werden.
Der Zugriffsplan der Abfrage wurde erneut erstellt.
Abfrageoptionsdatei kann nicht abgerufen werden.
****: Debug-Nachrichten des Optimierungsprogramms für Abfrage werden
gestartet.
Abfrageoptionsdatei kann nicht abgerufen werden.
Abfrageoptionsdatei kann nicht abgerufen werden.
Temporäre Datei für Datei MITEM erstellt.
Der Zugriffsplan der Abfrage wurde erneut erstellt.
Alle Zugriffspfade wurden für Datei V#VSTA00 berücksichtigt.
Zusätzliche Ursachencodes für Zugriffspfad verwendet.
Zugriffspfad für Datei *QUERY0004 erstellt.
Datei V#VSTA00 in Verknüpfungsposition 1 verarbeitet.
Datei *QUERY0004 in Verknüpfungsposition 2 verarbeitet.
Datei V#TAMH00 in Verknüpfungsposition 3 verarbeitet.
Datei V#TALI00 in Verknüpfungsposition 4 verarbeitet.
Abfrageoptionsdatei kann nicht abgerufen werden.
****: Debug-Nachrichten für Abfrage werden beendet.
ODP erstellt.
Blockung für Abfrage.
>> enddbg

Schlau geworden bin daraus allerdings nicht :-(

Weiß immer noch nicht, weshalb der Left Outer Join nicht so funktioniert, wie er sollte.

BenderD
21-05-08, 12:16
- das mit dem Parallelismus bedeutet, dass es schneller geht, aber mehr Strom braucht
- für die Differenzen wirst du dich schon mit deiner where klausel beschäftigen müssen, die sieht für mich eh suspekt aus

D*B

Tobse77
26-05-08, 10:15
Hallo,

habe den Fehler gefunden !!
Wie Dieter schon vermutet hat, liegt es nicht am Left Outer Join, sondern an der Where-Anweisung !!
In den beiden SQL-Statements
And Case When :imhptgr <> ' ' Then :imhptgr Else mi1v22 end
= mi1v22
und
And Case When :iuland <> ' ' Then :iuland Else mi1v19 end = mi1v19

frage ich mit mi1v22 (Marken-Gruppe der TNr) und mi1v19 (Ursprungsland der TNr) Felder ab, die sich nicht in der führenden Datei (Alias: Statistik) befinden, sondern in der Datei MITEM (Teilestamm). Und das ist genau die Datei, welche die Suffix-Teile nicht beinhaltet !!

Soweit die Fehlerergründung...

Jetzt stehe ich allerdings vor der Frage, wie ich dies beheben kann. Die beiden Case-Anweisungen darf ich nicht einfach eliminieren, da der Benutzer seine Auswertung sonst nicht mehr über Marken-Gruppe oder Ursprungsland selektieren kann.
Gibt es in SQL eine Möglichkeit, die es mir erlaubt um diese beiden CASE-Anweisungen herum eine Bedingung zu definieren, so dass die CASE-Anweisung nur dann greift, wenn der Satz in der Datei MITEM gefunden wurde?? Vermutlich aber wohl nur wenn ich die Daten satzweise einlese, oder?

Falls jemand eine zündende Idee hat, bitte her damit :-)

BenderD
26-05-08, 10:51
And Case When :imhptgr <> ' ' Then :imhptgr Else
coalesce(mi1v22, ' ')
end = coalesce(mi1v22, ' ')

oder auch:

(And Case When :imhptgr <> ' ' Then :imhptgr Else mi1v22 end
= mi1v22
or mi1v22 is null)

D*B


Hallo,

habe den Fehler gefunden !!
Wie Dieter schon vermutet hat, liegt es nicht am Left Outer Join, sondern an der Where-Anweisung !!
In den beiden SQL-Statements
And Case When :imhptgr <> ' ' Then :imhptgr Else mi1v22 end
= mi1v22
und
And Case When :iuland <> ' ' Then :iuland Else mi1v19 end = mi1v19

frage ich mit mi1v22 (Marken-Gruppe der TNr) und mi1v19 (Ursprungsland der TNr) Felder ab, die sich nicht in der führenden Datei (Alias: Statistik) befinden, sondern in der Datei MITEM (Teilestamm). Und das ist genau die Datei, welche die Suffix-Teile nicht beinhaltet !!

Soweit die Fehlerergründung...

Jetzt stehe ich allerdings vor der Frage, wie ich dies beheben kann. Die beiden Case-Anweisungen darf ich nicht einfach eliminieren, da der Benutzer seine Auswertung sonst nicht mehr über Marken-Gruppe oder Ursprungsland selektieren kann.
Gibt es in SQL eine Möglichkeit, die es mir erlaubt um diese beiden CASE-Anweisungen herum eine Bedingung zu definieren, so dass die CASE-Anweisung nur dann greift, wenn der Satz in der Datei MITEM gefunden wurde?? Vermutlich aber wohl nur wenn ich die Daten satzweise einlese, oder?

Falls jemand eine zündende Idee hat, bitte her damit :-)

Tobse77
26-05-08, 11:12
SPITZE Dieter !!! :-)

Genau so funktioniert's !!
Hatte mir schon mit einer 2. SQL-Anweisung in Abhängigkeit von den Eingabefeldern beholfen, aber dieser Weg ist natürlich weitaus eleganter - und wohl auch effizienter.

VIELEN DANK !!