Documente Academic
Documente Profesional
Documente Cultură
el nombre de la transaccin que declaramos al lado del for each (que debe ser la
transaccin cuya tabla fsica asociada queremos recorrer).
Adems, los atributos declarados dentro del for each (printblocks, where, order,
etc.), deben pertenecer a la tabla extendida de la tabla base del for each.
GeneXus al crear tablas fsicas crea para ellas un ndice por el atributo primario de
la tabla (es decir, por su clave primaria sea simple o compuesta) y un ndice por
cada clave fornea. Esto lo hace para que sean ms eficientes los controles de
consistencia de los datos entre tablas, como veremos en la siguiente pgina.
Podemos ver que se crearn tres ndices, con los nombres que vemos. Uno por la
Primary Key, y dos por las Foreings Keys. Por qu no se crea un ndice por
CountryId solo? Porque es innecesario. Si tenemos un ndice compuesto por
CountryId, CityId, ese ndice ya es, en particular, un ndice por CountryId.
Estos ndices, como decamos, se crean para hacer eficientes los controles de
integridad referencial que GeneXus realiza automticamente en las transacciones.
Los ndices por clave primaria se crean en las tablas para hacer eficiente el
control de duplicados, y tambin para hacer eficiente la bsqueda cuando desde
otra transaccin se est queriendo insertar o modificar la clave fornea que refiere a
esa clave primaria. En el ejemplo, cuando desde Attraction se est ingresando una
nueva atraccin, y hay que chequear que exista una categora en la tabla Category
con ese valor de CategoryId. All se utiliza el ndice por PK de Category (ICategory).
Los ndices por clave fornea se crean en las tablas para que cuando desde una
transaccin que tiene la clave primaria a la que esa clave fornea refiere, en
nuestro caso Category, se quiera eliminar un registro, se pueda saber rpida y
eficientemente si existe algn registro relacionado, para, en ese caso, impedir la
eliminacin. En nuestro caso, si vamos a eliminar una categora desde la
transaccin Category, GeneXus debe saber, para permitirlo, que no existe ninguna
atraccin con esa categora. Entonces usa el ndice IAttraction2 de Attraction.
Como habamos visto en la clase sobre relaciones 1 a 1, para cada nivel de cada
transaccin es obligatorio definir el atributo o conjunto de atributos que conforman
el identificador del nivel. Ese identificador se traducir a nivel de la tabla fsica en la
clave o llave primaria de la tabla. Con esto estamos diciendo que los valores de
este atributo o conjunto de atributos no podrn repetirse.
Debemos crear un ndice por el atributo CustomerDNI, e indicarle que ser de tipo
Unique. Es decir, indicarle que no podrn repetirse sus valores.
De esta manera, GeneXus interpretar que debe utilizar cada ndice unique que
tenga definida la tabla para controlar la unicidad de esos valores. Es decir, si se
est ingresando un nuevo cliente y el usuario digita un DNI que ya existe para otro
cliente, la transaccin disparar un error informando sobre esta situacin y no
permitir grabar el registro nuevo.
Ya habamos visto que si agregamos una clusula order para ordenar por nombre
de atraccin, el listado de navegacin nos da un aviso, informndonos de que en la
base de datos no existe un ndice por el atributo por el que necesitamos ordenar la
informacin, por lo que podramos tener baja performance para esta consulta.
Cuando se define una consulta, si hay un ndice fsico creado en la tabla por el
atributo a ordenar, GeneXus lo usar. Pero en este caso la consulta se necesita
ordenada por un atributo secundario: AttractionName. Y GeneXus nos advierte en
el listado de navegacin asociado al objeto, que no hay un ndice definido.
La existencia del ndice optimizara la consulta. Pero la desventaja de crear un
ndice es que, a partir de all, debe ser mantenido. Es decir, si los usuarios van
agregando, modificando o eliminando atracciones en la tabla ATTRACTION, debe
reacomodarse el ndice (o sea, los punteros del ndice deben reacomodarse de
forma tal de tener incluidas las nuevas atracciones, donde correspondan, para
mantener el orden).
Los tres primeros que vemos en el ejemplo, que aparecen antecedidos por el prefijo
I, son los creados automticamente por GeneXus a partir de las claves primaria y
forneas.
Necesitamos crear uno nuestro, es decir de usuario. Para ello presionamos enter,
tras lo que aparecer el nombre por defecto UAttraction. Lo modificamos a nuestro
gusto (agregndole Name al final, por ejemplo). El prefijo U es por User.
Tener varias clusulas where es equivalente a tener una sola, donde las
condiciones se conjugan con el operador lgico and. Es decir, se considerarn
slo los registros que cumplan con todas las condiciones a la vez.
Si vamos a filtrar por AttractionName, y tenemos un ndice creado por ese atributo,
nos convendr siempre ordenar por AttractionName para optimizar la consulta.
De hacerlo,
Observemos que ordenando por el atributo por el que estamos filtrando por menor o
igual y por mayor o igual hace que no se recorra toda la tabla. En caso de existir
ndice creado por el desarrollador, GeneXus utiliza ese ndice y la consulta estar
optimizada.
Es posible condicionar los ordenamientos y los filtros, para que slo se apliquen
ante determinadas circunstancias? Por ejemplo, que slo se aplique el primer
where cuando la variable &NameFrom no est vaca. Y que slo se aplique el
segundo where cuando la variable &NameTo no est vaca. La respuesta es s. Lo
conseguimos condicionando las clusulas where con when, como vemos en el
segundo for each. Slo se aplicar cada where cuando la condicin del when se
satisfaga. As, en ejecucin, cuando dejemos ambas variables vacas, no se
aplicar ninguno de los where, por lo que saldrn listadas todas las atracciones de
la tabla. Si la variable &NameFrom est vaca pero &NameTo no, no se aplicar el
primer where pero s el segundo, por lo que se listarn todas las atracciones cuyo
nombre ser menor o igual a &NameTo.
Todos los comandos que se escriban entre el when none y el endfor se ejecutarn
secuencialmente y en el nico caso en que no se hayan encontrado registros
de la tabla base del for each que cumplieran las condiciones.
En nuestro caso hemos decidido imprimir un mensaje, pero se podran escribir una
serie de comandos, como otro for each, por ejemplo.
Dejamos en gris todo lo que ya habamos visto antes. Aqu se agregan las
clusulas when y when none.