View Full Version : SQL inner join
Hi *all
bin grad böse auf SQL eingefallen
Ich bau in einem pgm ein SQL-Statement zusammen:
select file1.*, file2.* rrn(file1), RRN(file2) form file1 inner join file2 on blabla bla
anschliesend Prepare, open und dann in einer Schleife
fetch und verarbeitung
So.
Das Pgm läuft mehrere Minuten.
(in der zwischenzeit wird von allen Anwendern weitergearbeitet)
nun habe ich festgestellt, das Sätze der Datei FILE2 nicht aktuell sind sondern den Stand des Prepares haben
Ein Update auf File2 macht also zwischenzeitliche Änderungen aus anderen Programmen auf File2 kaput.
1. Frage: ist das so ?
2. Frage: habt ihrs gewußt ?
3. Frage: hilft ein 'optimize for 1 Row'?
oder was sonnst
Gruß vom Steinhuder Meer
Robi
Hallo,
das ist bei read only (wg. Felder aus zwei Dateien) Cursor, unter default commit level (dirty read) oder gar ohne commit, insensitivem Cursor (ebenfalls default) und der Erlaubnis temporäre Kopien zu ziehen (sagt man beim Wandeln, ebenfalls default) völlig normal. Optimize for 1 row hilft da nix, man muss den cursor sensitive machen, das ist eine Klausel beim declare cursor (depends on release, siehe Reference).
mfg
Dieter Bender
Hi *all
bin grad böse auf SQL eingefallen
Ich bau in einem pgm ein SQL-Statement zusammen:
select file1.*, file2.* rrn(file1), RRN(file2) form file1 inner join file2 on blabla bla
anschliesend Prepare, open und dann in einer Schleife
fetch und verarbeitung
So.
Das Pgm läuft mehrere Minuten.
(in der zwischenzeit wird von allen Anwendern weitergearbeitet)
nun habe ich festgestellt, das Sätze der Datei FILE2 nicht aktuell sind sondern den Stand des Prepares haben
Ein Update auf File2 macht also zwischenzeitliche Änderungen aus anderen Programmen auf File2 kaput.
1. Frage: ist das so ?
2. Frage: habt ihrs gewußt ?
3. Frage: hilft ein 'optimize for 1 Row'?
oder was sonnst
Gruß vom Steinhuder Meer
Robi
Join's sind immer temporär (ggf. Kopie der Daten) und werden beim Open nicht beim Prepare ermittelt.
Du benötigst einen Dynamic-Scroll-Cursor.
Dann ist es aber wichtig, dass du für die On-Beziehung und Where-Klause die richtigen Zugriffspfade hast.
Ein Problem könnte noch die RRN-Funktion haben, da die ggf. nicht optimierbar ist oder den Dynamic-Cursor verhindert.
Wofür brauchst du die überhaupt ?
Stimmt, Sensitive ist jetzt neurdings erforderlich (war früher nicht so).
Hallo
das mit dem sensitive und dem dynamic scroll, das ist so wie mit Library, Collection und Schema, sensitive ist der SQL politisch korrekte Ausdruck, dynamic scroll ist der DB2/400 Dialekt. Ich habe auf die Referenz verwiesen, weil das im kleingedruckten nicht immer so platt ist, da müssen je nach Konstellation mehrere Klauseln aufeinander abgestimmt sein.
Mit der RRN, das stimmt natürlich, die hat im SQL grundsätzlich nix zu suchen, damit schafft man sich Stress, der vermeidbar ist.
Ich sage jetzt noch mal was ketzerisches: temporäre Tabellen machen nur für zwei Fälle Sinn: read only Dateien (Datawarehouse, Statistik) oder grobe Schätzungen (füllen von Subfiles) ansonsten lässt man da die Finger von.
mfg
Dieter Bender
Join's sind immer temporär (ggf. Kopie der Daten) und werden beim Open nicht beim Prepare ermittelt.
Du benötigst einen Dynamic-Scroll-Cursor.
Dann ist es aber wichtig, dass du für die On-Beziehung und Where-Klause die richtigen Zugriffspfade hast.
Ein Problem könnte noch die RRN-Funktion haben, da die ggf. nicht optimierbar ist oder den Dynamic-Cursor verhindert.
Wofür brauchst du die überhaupt ?
Stimmt, Sensitive ist jetzt neurdings erforderlich (war früher nicht so).
Hallo guten Morgen!
Ein Problem könnte noch die RRN-Funktion haben, da die ggf. nicht optimierbar ist oder den Dynamic-Cursor verhindert.
Wofür brauchst du die überhaupt ?
Na ja, das ist halt ein Pgm das mit den gelesenen Sätzen
und anderen Dateien ein bisserl rumrechnet und anschl. die Dateien updatet.
Da wir mit 'Lese und Schreib'-Programmen arbeiten (Es gibt keine F-Karte in den Programmen, zum lesen und schreiben wird ein Pgm gerufen) brauchen wir die Satznr. Die ist Basis für das Schreiben .
Du benötigst einen Dynamic-Scroll-Cursor.
Dann ist es aber wichtig, dass du für die On-Beziehung und Where-Klause die richtigen Zugriffspfade hast.
DECLARE C1 DYNAMIC SCROLL CURSOR FOR SEL_FLD
ist dann wohl das richtige
Zugriffspfade sind ok
Vielen Dank euch beiden
gruß
Robi
das Programm habe ich geändert und an den Kunden geschickt.
Heute kommt ne Meldung, das das programm imernoch Daten
zerstört (beim Update alte Sätze schreibt)
d.h. Das Pgm 'liest' immernoch den Inhalt der Datensätze zum Zeitpunkt des Open und nicht des Fetch
C/EXEC SQL
C+ DECLARE C1 DYNAMIC SCROLL CURSOR FOR SE_FLD
C/END-EXEC
fehlt mir noch was
@Fuerchau
<ZITAT>
Join's sind immer temporär (ggf. Kopie der Daten) und werden beim Open nicht beim Prepare ermittelt.
Du benötigst einen Dynamic-Scroll-Cursor.
Dann ist es aber wichtig, dass du für die On-Beziehung und Where-Klause die richtigen Zugriffspfade hast.
</ZITAT>
Immer Temporär ? dann geht das also nicht ? trozu dynamic-scroll-cursor ?
Danke
Robi
Hallo,
der dynamic scroll cursor kann allenfalls sicher stellen, dass die Daten tatsächlich beim Fetch geholt werden (wobei man da nochmal in der Reference und bei der Wandlung genau nachsehen sollte, ob das auch so erstellt wird, oder per warning unterlassen wird). Was dann zwischen fetch und update passiert, steuert das commit level und was da genau unter blablabla zu verstehen ist.
mfg
Dieter Bender
das Programm habe ich geändert und an den Kunden geschickt.
Heute kommt ne Meldung, das das programm imernoch Daten
zerstört (beim Update alte Sätze schreibt)
d.h. Das Pgm 'liest' immernoch den Inhalt der Datensätze zum Zeitpunkt des Open und nicht des Fetch
C/EXEC SQL
C+ DECLARE C1 DYNAMIC SCROLL CURSOR FOR SE_FLD
C/END-EXEC
fehlt mir noch was
@Fuerchau
<ZITAT>
Join's sind immer temporär (ggf. Kopie der Daten) und werden beim Open nicht beim Prepare ermittelt.
Du benötigst einen Dynamic-Scroll-Cursor.
Dann ist es aber wichtig, dass du für die On-Beziehung und Where-Klause die richtigen Zugriffspfade hast.
</ZITAT>
Immer Temporär ? dann geht das also nicht ? trozu dynamic-scroll-cursor ?
Danke
Robi
Ausserdem muss man noch bedenken, dass bei Joins ggf. auf Kopien zugegriffen wird (ALWCPYDTA), gibts auch irgend eine QAQQINI-Einstellung dafür.
Desweiteren wird beim Lesen auch häufig geblockt, so dass bereits mehrere Sätze im Puffer stehen, während andere "lustig" die Daten bereits verändern.
Das hat auch gar nichts mit SQL zu tun, sonder geschieht auch bei (ILE)RPG.
Verarbeite ich eine Datei sequentiell mit Input, kann ich für späteren Update nicht garantieren, dass die Daten noch korrekt sind.
Hierfür gibts das Konzpt der Satzsperren, so dass ich bei einer U-Datei den Satz vor Änderungen schütze.
Bei SQL geht das nur, wenn die Dateien journalisiert werden, da ich dann mit dem entsprechenden Commitlevel bereits beim Lesen sperren kann. Ansonsten erlaubt SQL (wie bei I-Dateien) jederzeit einen "Dirty"-Read !
Um also "alten" Schrott nicht zurückzuschreiben muss man entweder journalisieren, oder (so machts z.B. MS-Access automatisch):
update myfile set field=newval
where myfile.key=mykey and field=oldval
SQLCOD=0 bedeutet, Update erfolgreich, SQLCOD=100 bedeutet
a) Satz nicht mehr da oder
b) Oldval stimmt nicht mehr
Die RRN kann da eher tödlich werden, da diese je nach Methode inzwischen anders sein kann.
Es soll Anwendungen geben, die einen zu verändernden Satz vorher löschen und dann neu anlegen. Die RRN ist daher nie eine Garantie, dass diese hinterher auch wieder stimmt.