Anmelden

View Full Version : SELECT..FOR UPDATE/Embedded SQL



KB
24-10-01, 09:47
Hallo,
ich bekomme einen Fehlermeldung, wenn ich in einem RPG-Programm ein "SELECT...FOR UPDATE" einbauen will. Das sei im embedded SQL nicht erlaubt??????!!!!
Was habe ich denn dann für eine Möglichkeit genau diesen Satz zu sperren?
Gruss und Danke
KB

rmittag
24-10-01, 15:55
Das wird über den COMMIT Parameter bei der Umwandlung gesteuert.

Möglich ist auch eine dynamische Steuerung über



c/Exec SQL
c+ SET OPTION COMMIT =
c/End-Exec


und für ganz mutige gibt es (glaube ich) auch ein API

Gruß Rolf

[Dieser Beitrag wurde von rmittag am 24. Oktober 2001 editiert.]

B.Hauser
25-10-01, 05:52
Hallo KB,

ich hatte bisher noch nie Probleme mit embedded SQL und for update of Definition

Anbei ein Beispiel, das sich sowohl mit commit = *CHG als auch *NONE umwandeln und anschliessend auch ausführen lässt:

C/EXEC SQL
C+ Declare $SQLC1 Cursor For
C+ Select ATBMN
C+ From HSATEIP
C+ where FIRNR = :$$FINR
C+ and ATBNR = 'HSWA_0514_001'
C+ For Update of ATBMN, ATUSEU, ATPGMU
C/END-EXEC
*
* SQL-Command Eröffnen
*------------------------*
C/EXEC SQL
C+ open $SQLC1
C/END-EXEC

* Verarbeiten SQL-Command in einer Schleife
*-------------------------------------------
C Do *HIVAL
*
C/EXEC SQL
C+ FETCH $SQLC1 INTO :$$BMN
C/END-EXEC
* Ende-Bedingungen
C If SQLCOD = 100
C Or SQLCOD< 0
C Leave
C Endif
*
* Verarbeitung
C/EXEC SQL
C+ Update HSATEIP
C+ Set ATBMN = :$$BMN + 10,
C+ ATUSEU = :§§USER,
C+ ATPGMU = :§§PGM
C+ Where Current of $SQLC1
C/END-EXEC
*
C enddo
*
* SQL-Command Schliessen
*------------------------*
C/EXEC SQL
C+ close $SQLC1
C/END-EXEC

tarkusch
28-04-16, 14:01
Hallo Frau Hauser,

ist es auch möglich im Select-Statement mehrere Dateien anzugeben?
Bekomme den Fehler SQL0511.



EXEC SQL
DECLARE CUR_C1 CURSOR FOR
SELECT T01.FIRMA, T01.PENR, T02.NAME
, T03.FELD1, T03.FELD2, T03.FELD3,
T04.FELD1
FROM FILE01 T01
INNER JOIN FILE04 T04
ON T04.LND = T01.LND
AND T04.MONAT = T01.MONAT
AND T04.FIRMA = T01.FIRMA
AND T04.PENR = T01.PENR
INNER JOIN FILE02 T02
ON T02.IDP = T01.IDP
AND T02.LND = T01.LND
AND T02.MONAT = T01.MONAT
INNER JOIN FILE03 T03
ON T03.LND = T01.LND
AND T03.MONAT = T01.MONAT
AND T03.FIRMA = T01.FIRMA
AND T03.PENR = T01.PENR
ORDER BY T01.LND , T01.FIRMA , T01.PENR
, T01.MONAT
FOR UPDATE OF Feld1, Feld2, Feld3


lg

Fuerchau
28-04-16, 14:12
Nein, ein Join kann nicht upgedated werden.
Hier benötigst du einen Single-Select.

tarkusch
28-04-16, 14:16
Oje, danke Vielmals für die rasche Antwort.

BenderD
28-04-16, 14:23
... das gilt mitlerweile auch nicht mehr unumschränkt. Wenn man das als View vernagelt, kann man auf selbige einen instead Trigger erstellen.

D*B

Fuerchau
28-04-16, 14:42
Ja, aber nicht per "update of" mit Satzsperre.
Das ist sowieso nicht SQL-Like. Frameworks generieren meist SQL's wie folgenden:

update mytable
set field = newvalue
where tablekey = key and field = oldvalue ...

Damit wird dann Konsistenz erreicht und ein "zerstörerischer" konkurierender Update verhindert.
Wenn man dann nicht per "select * " alle Felder verarztet können durchaus viele Anwendungen mit verschiedenen Teilen eines Satzes Updates durchführen.

Satzsperren verhindern doch konkurierendes Update?
Dem ist im Transaktionsumfeld mitnichten so.
Die (meisten) Frameworks arbeiten "offline". Es werden alle Informationen in interne Tabellen gelesen, dann werden diverse Änderungen gemacht (Ändern, Löschen, Hinzufügen) und anschließend der gesamte Update in einer Transaktion durchgeführt.
Zwischen Lesen und Update kann also genug Zeit vergehen in der eine Information geändert wurde.
Satzsperren gibt es da nicht.
Bei Fehlern kann man per Filter die fehlerhaften Daten harausbekommen und ggf. Rollback durchführen ansonsten halt Commit. Damit sind Sperren dann alle aufgehoben.
Nun kann man ja sagen, dass ich per Commitdefinition auch beim Lesen sperre, das funktioniert auch ohne Framework. Mit Framework wird die Verbindung aber durchaus getrennt somit sind Lese-Satzsperren nicht möglich.