À partir de la documentation Oracle :
Si votre requête fait référence à une seule table, il n'y a pas de différence entre FOR UPDATE
et FOR UPDATE OF ...
, mais ce dernier peut toujours être utile en tant qu'auto-documentation pour indiquer les colonnes que vous avez l'intention de mettre à jour. Cependant, cela ne limite pas ce que vous pouvez mettre à jour. Si vous avez :
CURSOR cur IS SELECT * FROM emp FOR UPDATE OF sal;
alors vous pouvez toujours faire :
UPDATE emp SET comm = comm * 1.1 WHERE CURRENT OF cur;
Mais s'il y a plus d'une table alors FOR UPDATE OF ...
verrouillera uniquement les lignes des tables qui contiennent les colonnes que vous spécifiez dans le OF
clause.
Contrairement à ce que je pense que vous dites dans la question. en spécifiant FOR UPDATE OF sal
ne verrouille pas seulement le sal
colonne; vous ne pouvez jamais verrouiller une seule colonne, le verrou minimum est au niveau de la ligne. (En savoir plus sur les verrous
). Il verrouille toutes les lignes de la table contenant le SAL
colonne, qui sont sélectionnés par la requête.
Dans la mise à jour de votre question, votre requête de curseur rejoint emp
et dept
, mais le OF
la clause n'a que sal
, une colonne dans le emp
table. Les lignes dans le emp
la table sera verrouillée lorsque le curseur est ouvert, et ces verrous ne seront pas libérés tant que vous n'aurez pas commit
ou rollback
cette séance. Dans votre boucle de curseur, vous pouvez faire :
UPDATE emp SET ... WHERE CURRENT OF emp_cur;
... pour mettre à jour la ligne dans le emp
tableau qui se rapporte à cette itération de la boucle. Vous ne pouvez pas faire :
UPDATE dept SET ... WHERE CURRENT OF emp_cur;
... parce que les lignes dans le dept
table ne sont pas verrouillées, car aucune colonne n'était dans le OF
. Cela signifie également que lors de votre deuxième session, le dept
les lignes peuvent être mises à jour librement, car elles ne sont pas verrouillées par la première session.