PDA

View Full Version : SQL inner join



Robi
19-01-07, 16:44
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

BenderD
19-01-07, 17:58
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

Fuerchau
19-01-07, 19:08
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).

BenderD
20-01-07, 08:34
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).

Robi
22-01-07, 09:35
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

Robi
22-06-07, 13:06
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

BenderD
22-06-07, 13:27
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

Fuerchau
22-06-07, 15:52
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.