PiensoPienso: Modificando registros seleccionados dentro del for each


Un problemita sencillo para un fin de semana largo.

Tengo una aplicación GeneXus y una tabla con la estructura y valores:

Key,Value
1 ,'NADA'
2 ,'NADA'
3 ,'NADA'

hago un procedure que hace

for each where Value='NADA'
Msg('Key: ' + Key.ToString() + ' Value: ' + Value)
UpdateValue.call(2,'TODO')
endfor

y

UpdateValue
parm(&Key,&Value);
for each where Key=&Key
Value=&Value
endfor

Notar que se modifica los datos de la tabla que cumplen la condición cuando se está dentro del for each.

La pregunta:

La salida del programa al ejecutar es (justifique su respuesta):

1)
Key = 1 Value='NADA'
Key= 2 Value='NADA'
Key=3 Value='NADA'

2)
Key = 1 Value='NADA'
Key=3 Value='NADA'

3)
Key = 1 Value ='NADA'
Key = 2 Value='TODO'
Key = 3 Value='NADA'

Como es habitual, habrá importantes reconocimientos para los que contesten correctamente.

Comentarios

  1. humm.. me suena la respuesta nro 3. No se como justificar la respuesta el unico registro que se machea y actualiza es el registro que tiene el valor igual a 2. los otros no entra en el registro.

    cordiales saludos!

    PD: muy feliz dia del trabajador para todos!

    ResponderEliminar
  2. Cuando el for each esta por arrancar las iteraciones, ya tiene en memoria los registros que verifican la condición, por lo tanto, creo que es la 1).

    saludos!!
    Bruno

    ResponderEliminar
  3. Salgo de "opinador" a ver si le pego.

    Pienso que el caso 1 se justifica para los generadores que utilizan SQL (Java, .NET , VFP, etc).
    O sea, ejecutan una sentencia y obtienen todos los registros a procesar. Luego por mas de que se haga una modificación, la navegación principal no varía (Sus valores en el momento de lectura).
    Ahora bien, el resultado de la salida es la mencionada por el caso 1, pero el resultado luego del commit es el caso de los valores mencionados en el punto 3.

    Sin embargo me quedan las dudas de aquellos que utilizan accesos secuenciales, tendría que probarlo en RPG o COBOL a ver como se comporta.
    Para esos casos pienso que puede ser el caso 2, en donde lee de forma secuencial los registros y se saltea el que fue cambiado.

    Me imagino que en RPG/COBOL se hará una apertura del indice y se irá recorriendo, pero en el momento en que el valor es actualizado en el acceso al primer registro, el segundo registro no tendrá el valor 'NADA', por lo que pasará a leer el tercer registro (Sería el caso 2).

    De todas formas vuelvo a mencionar que tendria que verificar el caso de RPG y COBOL, ya que estoy un poco oxidado con estas versiones.
    En una de esas en esos casos RPG o Cobol produzcan un error.

    ResponderEliminar
  4. Me encanta ver las diferentes opciones que estos pequeños ejemplos producen.

    Israel, Bruno y David:
    La solución 1) es la correcta para los modelos basados en SQL, y el motivo es el que dice Bruno.

    Gracias a todos por los comentarios y opiniones. Esperemos que esto le sirva a alguien .

    PD: No quise complicar la cosa con temas de ISOLATION LEVELS, COMMITS y demas..

    ResponderEliminar
  5. Definitivamente la respuesta es la 2,, indistintamente del generador que se esté utilizando,, la primera fila que se lee es la del Key = 1 y el Value = NADA,,luego se se ejecuta la instruccion que invoca al procedimeinto para actualizar la fila cuya clave es 2 con el valor 'TODO'..ante eso la siguiente fila tomada por el for each no será la 2 sino la 3 mostrando el valor = 'NADA'

    ResponderEliminar
  6. Xavier:
    La salida del programa, no es la 2) sino la 1).
    La seleccion de los registros, se hace antes de la actualizacion.

    ResponderEliminar

Publicar un comentario

1) Lee el post
2) Poné tu opinión sobre el mismo.
Todos los comentarios serán leidos y la mayoría son publicados.

Entradas más populares de este blog

El Sordo

StackOverflow Documentation

Paleta de colores en GeneXus