29
Edmundo Cáceres Práctica sobre consultas y vistas 2008

Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

  • Upload
    hahuong

  • View
    217

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo Cáceres

Práctica sobre consultas y vistas

2008

Page 2: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 1 —

Consultas Ejercicio 1 Cree una consulta con los campos ART y NOM de la tabla ART, que muestre los nombres de los artícu-los ordenados alfabéticamente, de menor a mayor. 1. Cree una consulta. Puede hacerlo con ARCHIVO – NUEVO – CONSULTA– NUEVO ARCHIVO. Otra forma

es ubicarse en la categoría CONSULTAS de un proyecto, pulsar el botón NUEVO y después el botón NUEVA CONSULTA. Una tercera forma es emitir el comando CREATE QUERY seguido por el nombre que va a tener la nueva consulta. Se abre el DISEÑADOR DE CONSULTAS, en blanco. Dado que supone-mos que cuenta con el proyecto FAC, use la segunda forma. Toda consulta trabaja sobre una o más tablas y/o vistas de entrada. Por ello, junto al diseñador se abrirá un diálogo para seleccionar una de estas entradas. Si hay alguna base de datos (BD) abier-ta, el diálogo será AGREGAR TABLA O VISTA, para elegir lo necesitado. Si no hay una BD abierta, el diálogo será ABRIR, para agregar la primera tabla. Luego se cierra este diálogo, que es reemplaza-do por AGREGAR TABLA O VISTA, siempre que la tabla abierta sea de BD. Esto se debe a que VFP ob-tiene de la primera tabla agregada información sobre la BD a que pertenece: esto explica el reem-plazo del diálogo, dado que el segundo es más práctico y permite elegir la categoría VISTAS. Este segundo diálogo permanece abierto para seguir agregando tablas o vistas, mediante el botón AGREGAR. Para cerrarlo se usa el botón CERRAR. Este diálogo se puede abrir posteriormente en cualquier momento, eligiendo la opción AGREGAR TABLA del menú contextual sobre el DISEÑADOR DE CONSULTAS. El botón OTRAS de AGREGAR TABLA O VISTA sirve para elegir tablas que no pertenezcan a las BD abiertas, las cuales aparecen en la cuadro combinado BASES DE DATOS. El botón OTRAS presenta el diálogo ABRIR. Estas tablas adicionales pueden ser libres o de otras BD. En el segundo caso, se abrirá la tabla y la BD a que pertenece, agregándose el nombre de ésta a la lista del cuadro combi-nado. En AGREGAR TABLA O VISTA, bajo el nombre SELECCIONAR hay dos botones: TABLAS y VISTAS. Estos botones cambian lo que muestra el cuadro de lista cuya etiqueta dirá TABLAS EN LA BASE DE DATOS y VISTAS EN LA BASE DE DATOS.

2. Agregue la tabla ART, que se verá como un cursor en el panel superior (entorno) del DISEÑADOR DE CONSULTAS. Cada tabla o vista agregada se representa en el panel superior como cursor. En cada uno se listan verticalmente sus campos, precedidos por un asterisco, que representa todos los campos del cur-sor. Todos los campos de los cursores agregados aparecen en el cuadro CAMPOS DISPONIBLES de la ficha CAMPOS, prefijados con el nombre del cursor respectivo.

3. En la ficha CAMPOS, transfiera los campos ART.ART y ART.NOM de la lista CAMPOS DISPONIBLES a la lista CAMPOS SELECCIONADOS. Usando CAMPOS DISPONIBLES, la transferencia de un campo se puede hacer seleccionándolo y pul-sando el botón AGREGAR, dándole doble click o arrastrándolo a la lista CAMPOS SELECCIONADOS. Usando el cursor, se puede hacer con doble click o arrastrándolo. Para transferir todos los campos de todos los cursores se usa el botón AGREGAR TODOS. Para trans-ferir todos los campos de un solo cursor se usa el asterisco, con doble click o arrastre. Para transferir a la vez algunos campos, se los selecciona en CAMPOS DISPONIBLES o en un cursor y se usa el botón AGREGAR o el arrastre.

Page 3: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 2 —

La devolución de un campo de CAMPOS SELECCIONADOS a CAMPOS DISPONIBLES se hace seleccio-nándolo y pulsando QUITAR, dándole doble click o arrastrándolo. La devolución de todos los campos se hace con el botón QUITAR TODOS. Para devolver algunos campos de un mismo cursor, se los selecciona y se pulsa QUITAR o se los arrastra. Los campos seleccionados son los que la consulta va a producir, contenidos en un cursor que se verá en la ventana EXAMINAR. En este primer ejemplo no veremos que la consulta hace gran cosa, porque lo mismo podríamos lograr examinando la tabla ART. Sin embargo, a medida que avance-mos, veremos que tienen mucha potencia.

4. Seleccione la ficha ORDENAR POR y transfiera el campo NOM de CAMPOS SELECCIONADOS a CRITERIOS DE ORDENACIÓN. Los recursos para transferir campos son análogos a los explicados an-tes. En OPCIONES DE ORDEN active el botón ASCENDENTE. Las consultas permiten ordenar los registros del cursor de salida por uno o varios de sus campos. En este caso, solamente ordenamos por uno sólo, NOM. Note que los campos por los que podemos ordenar son los que componen el cursor de salida, no los de los cursores de entrada: los campos para ordenar son los seleccionados en la ficha CAMPOS.

5. Ejecute la consulta, eligiendo EJECUTAR CONSULTA en el menú contextual o en el menú CONSULTA. Veremos el resultado en una ventana EXAMINAR, de sólo lectura. Compruebe esto tratando de mo-dificar el contenido de cualquier campo: se nos dará el mensaje El control es de sólo lectura. Ve-remos luego que el resultado de las vistas también es un cursor que se ve en la ventana EXAMINAR, pero que permite modificar el valor de los campos.

6. Salga de la ventana EXAMINAR con ESC. 7. Guarde la consulta con el nombre CON1 y luego ciérrela.

Para guardar puede usar ARCHIVO – GUARDAR o ARCHIVO – GUARDAR COMO. Si el archivo aún no es-tá guardado, GUARDAR llamará al diálogo GUARDAR COMO. Si ya está guardado, guardará las nue-vas modificaciones. CTRL + S es igual a ARCHIVO – GUARDAR. Cierre el diseñador con ARCHIVO – CERRAR o con ESC. Si pulsa ESC y aún no ha guardado el archivo, VFP preguntará si lo quiere guardar. Si contesta que sí, se presenta el diálogo GUARDAR COMO y después se cierra el diseña-dor. Otra forma de guardar y salir es con CTRL + W, que pide un nombre para el archivo si todavía no lo tiene.

Ejercicio 2 Cree la consulta CON2, similar a CON1, pero que liste solamente los artículos cuyo código de artículo (campo ART), comience con la letra C. 1. Para aprovechar el trabajo realizado en CON1, seleccione este archivo en el proyecto FAC y pulse

MODIFICAR. Esto abrirá CON1 en el DISEÑADOR DE CONSULTAS. 2. Dé el comando ARCHIVO – GUARDAR COMO. En el diálogo de igual nombre, denomine CON2 al dupli-

cado a crear. Después de eso, verá que la consulta que queda en el diseñador es CON2, de modo que vamos a trabajar sobre ella. Para saber sobre qué consulta está trabajando, lea la barra de tí-tulo del diseñador.

3. Seleccione la ficha FILTRO. En NOMBRE DE CAMPO elija ART.ART. En CRITERIOS elija el operador = y en EJEMPLO escriba "C".

4. Guarde la consulta con CTRL + S y luego ejecútela. Salga con ESC de la ventana EXAMINAR y vuelva a dar ESC para salir del diseñador.

Page 4: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 3 —

5. La nueva consulta no aparece en el proyecto, porque si bien fue creada y modificada, no fue agre-gada a él. Para hacerlo, en el ámbito CONSULTAS del proyecto pulse AGREGAR. En el diálogo ABRIR seleccione el archivo CON2 y pulse ACEPTAR. Luego de ello, la nueva consulta quedará registrada en el proyecto y se verá dentro del ámbito CONSULTAS. La ficha FILTROS sirve para hacer que algunos registros de entrada entren al proceso de la consulta y otros no. Para ello se usa un campo, que se compara contra un valor. Si el resultado lógico de la comparación es verdadero, el registro entra al proceso; de lo contrario, el registro se ignora y no in-fluye en el cursor resultante. Que lo establecido en la ficha FILTROS afecta los registros de entrada se pone de manifiesto en la lista NOMBRE DE CAMPO, donde se ofrecen todos los campos de entrada, es decir, los mismos de la lista CAMPOS DISPONIBLES de la ficha CAMPOS o los que se ven en los cursores de entrada. En este ejercicio, el filtro se aplica al campo ART, que también figura en la lista CAMPOS SELECCIONADOS. Pe-ro podríamos haber aplicado el filtro al campo PRE, que no es un campo seleccionado para confec-cionar el cursor de salida. La ficha FILTROS permite descartar registros de entrada usando cualquiera de sus campos o expre-siones construidas sobre ellos, sin darles salida en el cursor resultante. Este campo o expresión se escribe en NOMBRE DE CAMPO. El filtro establecido en una consulta es estático: permanece fijo mientras no lo modifiquemos en la consulta. Puede darse el caso que usted diseñe la consulta CON2 para que la ejecuten otras per-sonas que no saben nada de diseño. Cuando se quiera que la consulta dé por resultado los regis-tros cuyo código de artículo comience con la letra A, B, D, etc., cualquier otra letra distinta a C, us-ted, el único experto en este tema, tendrá que modificar CON2. Ahora bien, ¿qué pasará cuando usted no esté presente, porque está enfermo o de vacaciones? Los demás no podrán obtener lo que deseen, hasta que usted no regrese. Este problema no puede solucionarse en las consultas, sino en las vistas, que usan una técnica llamada parametrización, tema que veremos posteriormen-te. En CRITERIOS aparecen distintos operadores, para comparar si un campo es igual, menor, mayor, etc., que el valor escrito en EJEMPLO. El botón NO sirve para negar el operador elegido, obteniendo no igual (distinto), no menor (mayor o igual), no mayor (menor o igual), etc. El operador =, aplicado a caracteres, considera la igualdad parcial del valor del campo y del ejem-plo, de izquierda a derecha, hasta que se acaba el ejemplo. Por ello, en el ejercicio, los valores C01, C02, C03, etc., del campo ART, son iguales al valor del ejemplo, C. El operador = puede apli-carse a campos o expresiones numéricas, de fecha, de fecha–hora y lógicas. El operador == da por iguales los valores del campo y del ejemplo cuando son totalmente iguales, no parcialmente iguales. El operador BETWEEN compara el valor de un campo con un intervalo de valores, que se expresan en EJEMPLO indicando el menor y el mayor, separados por una coma. Así, si en EJEMPLO hubiera escrito A,D, en el resultado vería todos los artículos cuyo código comienzan con A, B, C y D. El operador IN compara el valor de un campo con un conjunto de valores no sucesivos, que se ex-presan en EJEMPLO listándolos, separados por comas. Si en EJEMPLO hubiera escrito A, C, F, sólo vería los artículos cuyo código comienzan con A, C y F. No hace falta que los valores sean escritos en orden: podría haberlos indicado como A,F,C, como F,A,C o como F,C,A. El operador LIKE sirve para introducir comodines en el valor de EJEMPLO. A diferencia de los cono-cidos comodines ? y *, SQL usa _ (subrayado) para representar cualquier valor en una posición específica y % (porcentaje) para representar cualquier valor en en una o más posiciones. Por ejemplo, para filtrar los nombres de artículo que comienzan con A, LIKE exige expresar en EJEMPLO

Page 5: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 4 —

la expresión A% o "A%". Para filtrar los nombres que tienen una a minúscula en la segunda posi-ción, el filtro se escribe _a% o "_a%". Para filtrar los nombres que tienen dos a minúsculas en cual-quier posición, el filtro es %a%a% o "%a%a%". Los ejemplos dados evidencian que LIKE distingue entre mayúsculas y minúsculas. No comentamos el operador IS NULL, porque no nos interesa trabajar con valores nulos. Dado que el campo ART es de caracteres, SQL entiende que sólo se puede comparar contra carac-teres, por lo que, si no se escribe entre comillas el valor de EJEMPLO, lo corrige y lo encierra entre comillas. Para evitar problemas, escríbalo siempre entre comillas. El botón M / M sirve para distinguir entre mayúsculas y minúsculas, cuando no se activa. Si no lo ac-tiva y escribe c, no se listará ningún artículo que comience con c minúscula. Si lo activa y escribe C o c, listará todos los artículos que comiencen con esa letra.

Ejercicio 3 Se quiere una consulta CON3 que muestre los artículos cuyo precio, aumentado un 15%, supere $180. Los campos de salida serán ART, NOM y el nuevo precio. 1. Cree una nueva consulta. Agregue la tabla ART. En la ficha CAMPOS, agregue los campos ART y

NOM.

2. En FUNCIONES Y EXPRESIONES, llame al GENERADOR DE EXPRESIONES con . Cree la expresión ART.PRE * 1.15. Cierre el generador. La expresión queda en FUNCIONES Y EXPRESIONES.

3. Pulse el botón AGREGAR. Esto transfiere la expresión a CAMPOS SELECCIONADOS, como un campo calculado.

4. Seleccione la ficha FILTROS. En NOMBRE DE CAMPO seleccione <EXPRESIÓN…>. En el GENERADOR DE EXPRESIONES escriba ART.PRE * 1.15. En CRITERIOS seleccione > y en EJEMPLO escriba 180.

5. Ejecute la consulta. La columna del nuevo precio dice Exp_1 (o Exp_2, o Exp_3, etc., según la can-tidad de campos calculados agregados como campo seleccionado). Este título de la columna no es para nada claro, por lo que conviene darle otro más apropiado.

6. En la ficha CAMPOS, seleccione la expresión. Pulse el botón QUITAR, para sacar el campo calculado de CAMPOS SELECCIONADOS y devolverlo a FUNCIONES Y EXPRESIONES. Pulse . En el GENERADOR DE EXPRESIONES, corrija la expresión por ART.PRE * 1.15 AS NUEVO_PRECIO. Cierre el generador. Transfiera la expresión corregida a CAMPOS SELECCIONADOS con el botón AGREGAR.

7. Vuelva a ejecutar la consulta. Ahora la última columna tiene un nombre apropiado. Hemos escrito Nuevo_precio y no Nuevo precio, porque los nombres de campo no aceptan blancos. El guión bajo salva este problema.

8. Guarde la consulta con el nombre CON3. Para evitar perder el trabajo en caso de corte de energía, podría haberla guardado en cualquier paso intermedio, repitiendo la operación cada tanto con con CTRL + S. No olvide guardarla cuando todo esté concluido con éxito. El título de la tercera columna está bien y es completo, pero las otras columnas son ART y NOM, igual al nombre de los campos. Corrijamos estos títulos, para que tengan nombres completos.

9. En la ficha CAMPOS devuelva los campos ART y NOM. En FUNCIONES Y EXPRESIONES escriba ART.ART AS ARTÍCULO y transfiérala a CAMPOS SELECCIONADOS.

10. Haga lo mismo para el campo NOM, escribiendo la expresión ART.NOM AS NOMBRE. 11. En CAMPOS SELECCIONADOS aparecen tres campos calculados, pero no en el orden con que se des-

ea que aparezcan en la ventana EXAMINAR. El que está más arriba será la primera columna, el que

Page 6: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 5 —

le sigue será la segunda, y así. Para reordenarlos, mueva la disposición de los campos selecciona-dos tomándolos de los botones que los preceden y arrastrándolos hacia arriba o abajo.

12. Ejecute la consulta y guárdela cuando esté bien. Ejercicio 4 Se quiere una consulta CON4 que muestre todos los campos de la tabla LINFAC, agregando un campo calculado con el producto del precio por la cantidad. De este modo obtendremos el parcial de cada artí-culo que compone cada factura. El resultado debe estar ordenado por número de factura y dentro de cada número por el código de artículo. 1. Cree una consulta. Agregue la tabla LINFAC. En la ficha CAMPOS, agregue todos los campos a

CAMPOS SELECCIONADOS. 2. En FUNCIONES Y EXPRESIONES escriba LINFAC.PRE * LINFAC.CAN AS PARCIAL y agréguela a CAMPOS

SELECCIONADOS. 3. En la ficha ORDENAR POR, agregue el campo FAC a CRITERIOS DE ORDENACIÓN, con orden AS-

CENDENTE. Agregue luego el campo ART en orden ASCENDENTE. Si quisiéramos construir un índice por los mismos conceptos para la tabla LINFAC, deberíamos usar la expresión STR(LIFAC.FAC,8,0) + LINFAC.ART e indicar si el orden va a ser ascendente o descen-tente. El orden se aplica a la totalidad de la expresión, es decir, a cada componente. En las consul-tas cada componente puede tener su propio orden. Note que, aunque existiera tal índice, SQL no lo tiene en cuenta, por lo que hay que establecer el orden en la ficha ORDENAR POR.

4. Guarde y ejecute la consulta. Ejercicio 5 La consulta CON4 muestra los totales parciales de cada factura, pero no el total general de ellas. Se quiere una consulta, CON5, con el campo FAC y un campo calculado con la suma de los productos par-ciales entre cantidad y precio, para obtener el total general de cada factura. Los registros de salida de-ben estar ordenados por factura. 1. Cree una nueva consulta. Agregue la tabla LINFAC. Haga de FAC un campo seleccionado. 2. Agregue como campo seleccionado la expresión SUM(LINFAC.CAN * LINFAC.PRE) AS TOTAL. 3. Guarde y ejecute la consulta CON5.

Observe que la ventana EXAMINAR muestra un solo registro. ¿Por qué? La función SUM( ) suma la expresión numérica contenida o calculada en cada registro. Esto lo hace con todos los registros de la tabla LINFAC. Cuando ya no hay más registros a procesar, da por resultado un solo registro, con el total de lo calculado. Por eso se dice que SUM( ) es una función de agrupamiento. Si observa el registro resultante, el campo FAC se refiere a una sola factura, pero el campo TOTAL es el importe de todas las facturas. La información de FAC es incoherente, porque usted eligió este dato para la salida. La incoherencia la genera usted, no SQL. Como SQL debe dar salida a un nú-mero de factura, habiendo muchas facturas dará el número de la última que encuentre. Felizmente, dado que usted quiere el total de cada factura, hay una manera de lograrlo.

4. En la ficha AGRUPAR POR, transfiera el campo FAC de CAMPOS DISPONIBLES a CAMPOS AGRUPADOS. 5. Ejecute la consulta. Ahora sí los resultados son los esperados.

Observe que CAMPOS DISPONIBLES le ofrece agrupar por cualquier campo de la tabla, esté o no se-leccionado como salida. Si usa para agrupar un campo que no va a figurar en la salida, SQL lo

Page 7: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 6 —

agregar por su cuenta a CAMPOS SELECCIONADOS de la ficha CAMPOS. Pero si usted quiere agrupar por él pero no tenerlo en la salida, puede eliminarlo de esa lista. Quede claro, entonces, que el agrupamiento afecta los registros de entrada. En el ejemplo, como se quiere un total por cada factura, SQL ordena los registros de entrada de modo que primero que-den todos los correspondientes a la factura 1, formando un grupo, luego todos los correspondientes a la factura 2, etc. Teniendo los registros ordenados de esa manera, SQL puede dar un total co-rrecto de la factura 1, que muestra como un único registro en la salida. Lo mismo para la factura 2, etc. Insistamos en cómo trabaja el agrupamiento. Cuando se agrupa, SQL ordena los registros de en-trada por el criterio de ordenamiento, formando grupos. Luego, para todos los registros de un grupo de entrada, produce un solo registro de salida con lo calculado. Pone en cero lo calculado y repite el proceso para el grupo siguiente, produciendo otro registro de salida. La dicho en el párrafo anterior se aclara más ejemplificando con datos. Suponga que la tabla LINFAC tiene los siguiente registros, en orden de grabación.

Linfac Fac Art Can Pre

1 A05 5 10 2 B01 4 15 3 D03 1 20 1 C02 2 40 2 A05 2 10 1 A04 4 25 3 A02 1 90 3 A06 2 45 2 C01 5 50

Como debe agrupar por FAC, SQL ordena internamente los registros de entrada por tal campo, quedando:

Linfac ordenada Fac Art Can Pre

1 A05 5 10 1 C02 2 40 1 A04 4 25 2 B01 4 15 2 A05 2 10 2 C01 5 50 3 D03 1 20 3 A02 1 90 3 A06 2 45

Ahora puede calcular la expresión SUM(LINFAC.PRE * LINFAC.CAN) AS TOTAL. Comenzando por el grupo de la factura 1, el cálculo irá incrementándose como sigue:

Linfac ordenada Cálculos Fac Art Can Pre Linfac.pre * Linfac.can SUM(Linfac.pre * Linfac.can)

1 A05 5 10 50 50 1 C02 2 40 80 130 1 A04 4 25 100 230

Page 8: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 7 —

Cuando SQL llega a la factura 2, es porque se ha acabado completamente la factura 1. Entonces genera un registro de salida para la factura 1.

Cursor de salida Fac Total

1 230 Con la factura 2 hace lo mismo:

Linfac ordenada Cálculos Fac Art Can Pre Linfac.pre * Linfac.can SUM(Linfac.pre * Linfac.can)

2 B01 4 15 60 60 2 A05 2 10 20 80 2 C01 5 50 250 330

SQL genera un nuevo registro y lo agrega al cursor de salida: Cursor de salida

Fac Total 1 230 2 330

Finalmente, con la factura 3, SQL realiza los siguientes cálculos: Linfac ordenada Cálculos

Fac Art Can Pre Linfac.pre * Linfac.can SUM(Linfac.pre * Linfac.can) 3 D03 1 20 20 20 3 A02 1 90 90 110 3 A06 2 45 90 200

SQL agrega el total de la factura 3 al cursor de salida, en un nuevo registro: Cursor de salida

Fac Total 1 230 2 330 3 200

Aunque no hemos usado la ficha ORDENAR POR, los registros salen ordenados por factura. Esto es porque SQL, para hacer el cálculo, previamente ordenó internamente los registros de entrada por factura, como se ha indicado. Las entradas, entonces, tienen el orden necesitado para la salida. Si se necesitara otro orden para la salida, por ejemplo por TOTAL descendente, se puede hacer sin ningún inconveniente usando ORDENAR POR, que, como se ha dicho, ordena los registros de salida. Otra advertencia es que el agrupamiento se puede hacer por más de un campo. Por ejemplo, en la tabla ENCFAC podríamos agrupar por los campos CLI y FEC. Cada grupo esaría formado por el valor conjunto de ambos campos, de modo que, a los efectos del cálculo, es lo mismo la combinación CLI – FEC que FEC – CLI. Sin embargo, a los efectos del orden interno, que puede ser aprovechado sin usar la ficha ORDENAR POR, no es lo mismo. Por ello, en CAMPOS AGRUPADOS, cada campo tiene un botón que permite arrastrarlo hacia arriba o abajo, logrando el ordenamiento adecuado: el cam-po que está arriba es el que tiene mayor prioridad, la cual desciende por los demás campos de modo jerárquico.

Ejercicio 6 Se quiere una consulta CON6 que haga básicamente lo mismo que CON5, pero que solamente genere registros de totales para las facturas cuyos importes superen $1000.

Page 9: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 8 —

1. Abra CON5 y guárdela como CON6. Cierre CON5. Agregue CON6 al proyecto y ábrala para modifi-carla.

2. En la ficha AGRUPAR POR pulse el botón CONDICIONES. Esto trae un diálogo de igual nombre, que sirve para filtrar registros de salida.

3. En NOMBRE DEL CAMPO elija el campo calculado TOTAL. En CRITERIOS elija el operador >=. En EJEMPLO escriba 1000.

4. Ejecute y guarde la consulta. El botón CONDICIONES de la ficha AGRUPAR POR sirve para establecer filtros para los registros de sa-lida. Si usted quiere poner filtros a los totales de factura, no puede hacerlo en la ficha FILTROS, por-que los filtros establecidos en ella se aplican a los registros de entrada. Como los totales son una suma de los productos precio por cantidad de los registros componentes de cada factura, no exis-ten como datos de la entrada, sino que resultan de cálculos aplicados a cada grupo. Por ello los to-tales deben filtrarse en los registros de salida, para lo cual existe el diálogo CONDICIONES.

Ejercicio 7 Se quiere CON7 que haga lo mismo que CON5, pero que muestre las 10 facturas cuyo totales sean los mayores. 1. Guarde CON5 como CON7. Agregue CON7 al proyecto y entre a modificarla. 2. En la ficha ORDENAR POR, agregue SUM(LINFAC.PRE * LINFAC.CAN) AS TOTAL a CRITERIOS DE

ORDENACIÓN, con opción de orden DESCENDENTE. 3. Ejecute la consulta.

Aparecen todos los registros, ordenados de mayor a menor por TOTAL. Pero nosotros queremos so-lamente los 10 primeros registros de esa salida, que tienen los totales mayores.

4. En la ficha VARIOS, desactive el botón TODOS de REGISTROS INCLUIDOS y escriba 10 en NÚMERO DE REGISTROS.

5. Ejecute la consulta y guárdela. Si en lugar de los 10 mejores quisiera el 10% de los registros, deberá activar el botón PORCENTAJE.

Ejercicio 8 Cree CON8 para obtener el total vendido de cada artículo. 1. Cree una nueva consulta. Agregue la tabla LINFAC. Seleccione como salida el campo ART y la ex-

presión SUM(LINFAC.PRE * LINFAC.CAN) AS VENDIDO. 2. Agrupe por el campo ART. 3. Ejecute y guarde la consulta. Ejercicio 9 Cree CON9 para obtener todos los campos de la tabla LINFAC, agregando en cada registro el nombre de cada artículo, que debe tomar de la tabla ART. 1. Cree una consulta. Agregue la tabla LINFAC. Agregue todos los campos. 2. En el DISEÑADOR DE CONSULTAS, pulse el botón secundario y elija AGREGAR TABLA. 3. En el diálogo AGREGAR TABLA O VISTA, selecciones la tabla ART y pulse ACEPTAR. Esto abre el diálo-

go CONDICIÓN DE COMBINACIÓN, en el que se propone una combinación interna entre LINFAC.ART y ART.ART. Pulse ACEPTAR. Cierre el diálogo AGREGAR TABLA O VISTA.

Page 10: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 9 —

SQL puede fabricar salidas combinando dos tablas. Combinar es parecido a relacionar las tablas, pero no igual. SQL no maneja relaciones. Las combinaciones consideran situaciones que las rela-ciones no tienen en cuenta. Para combinar dos tablas, ambas deben tener algo común. En el ejemplo, lo común es el campo ART, que está en ambas tablas. Lo común no es que se llamen igual, sino que tengan datos referi-dos a lo mismo. Si en una tabla el campo se llamara ART y en la otra se llamara ARTIC, la combina-ción también podría hacerse, porque ambos contienen códigos de artículo. Al definir la combinación, se indica un campo de una tabla a la izquierda y un campo de otra tabla a la derecha. Esto permite hablar de tabla izquierda y tabla derecha. Fíjese que izquierda y derecha hacen referencia a cómo se definen las tablas en el diálogo CONDICIÓN DE COMBINACIÓN, no a como se ven en el entorno. En este panel, los cursores se pueden arrastrar a cualquier lado, de modo que hablar de tabla izquierda o derecha no tiene sentido, porque el arrastre puede poner la tabla izquierda a la derecha, una tabla bajo la otra, etc. Hay varios tipos de combinaciones. El tipo interna indica que SQL se va a preocupar por fabricar una salida cada vez que un registro de la tabla izquierda coincida con otro de la tabla derecha por el campo ART. Si un registro de la tabla izquierda no tiene un registro coincidente en la tabla dere-cha, se ignora. Sería el caso de un código de artículo vendido que fuera erróneo, porque no po-dríamos vender algo que no esté en la lista oficial de los artículos que comercializamos (tabla ART). Simétricamente, si un registro de la tabla derecha no tiene un registro coincidente en la tabla iz-quierda, también se ignora. Sería el caso de un artículo de la lista oficial que no se hubiera vendido nunca. Sean las tablas LINFAC y ART, con registros hipotéticos. Los registros de una tabla sin coincidencia en la otra aparecen oscurecidos.

Linfac Art Fac Art Can Pre Art Nom

1 A05 5 10 A01 Camisa 1 A04 4 25 A02 Pantalón 2 A09 4 15 A03 Corbata 2 A05 2 10 A04 Pañuelo 2 C01 5 50 A05 Cinto 3 A02 1 90 A06 Zapatos 3 A06 2 45 A07 Medias

SQL producirá la salida siguiente: Cursor de salida

Fac Art Can Pre Nom 1 A05 5 10 Cinto 1 A04 4 25 Pañuelo 2 A05 2 10 Cinto 3 A02 1 90 Pantalón 3 A06 2 45 Zapatos

Observe que el registro de ART con código de artículo A05 aparece en las facturas 1 y 2 de LINFAC. Esto significa que el registro de ART se combina con cada uno de los registros de LINFAC, produ-ciendo dos registros en el cursor de salida. Como no hemos ordenado la salida por código de artículo ni por nombre, es confuso. Mejor hubiera sido ordenar por alguno de estos campos.

Page 11: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 10 —

4. Guarde y ejecute la consulta. Ejercicio 10 Cree CON10 para calcular el importe total vendido de cada artículo. La salida debe ordenarse por nom-bre de artículo. 1. Cree una nueva consulta. 2. Agregue la tabla ART y luego la tabla LINFAC. 3. En el diálogo CONDICIÓN DE COMBINACIÓN, acepte la propuesta de combinar internamente ART.ART

con LINFAC.ART. Cierre el diálogo AGREGAR TABLA O VISTA. A los efectos de lograr el propósito de la consulta, en este caso es indistinto cuál tabla estará a la izquierda y cual a la derecha.

4. En la ficha CAMPOS agregue como campos seleccionados ART.ART, ART.NOM y la expresión SUM(LINFAC.CAN * LINFAC.PRE) AS VENDIDO.

5. En agrupar por agregue ART.ART como campo agrupado. 6. En ORDENAR POR agregue ART.NOM como criterio de ordenación. 7. Guarde y ejecute la consulta.

Hemos agrupado por código de artículo y hemos ordenado la salida por nombre de artículo. ¿Po-dríamos haber agrupado por el nombre? En el caso del ejercicio sí, porque todos los nombres son diferentes. Pero en la mayoría de los casos, como clientes, alumnos, socios, etc., es muy común que dos o más clientes, alumnos, etc., tengan códigos distintos, pero se llamen igual. Por ejemplo, sea que los clientes con código 15 y 49 se llamen Juan Carlos González. Si agrupáramos por nom-bre, daríamos un solo total para Juan Carlos González, lo cual sería un error. Lo correcto sería agrupar por código de cliente, que es el identificador de cada uno y nunca se repite. Si el código de cliente se repitiera, dejaría de ser identificador. Con las tablas del ejemplo anterior, SQL ordenaría las tablas por ART, para poder agrupar:

Linfac Art Fac Art Can Pre Art Nom

3 A02 1 90 A01 Camisa 1 A04 4 25 A02 Pantalón 1 A05 5 10 A03 Corbata 2 A05 2 10 A04 Pañuelo 3 A06 2 45 A05 Cinto 2 A09 4 15 A06 Zapatos 2 C01 5 50 A07 Medias

Luego produciría la combinación siguiente: Combinación

Fac Art Can Pre Nom 3 A02 1 90 Pantalón 1 A04 4 25 Pañuelo 1 A05 5 10 Cinto 2 A05 2 10 Cinto 3 A06 2 45 Zapatos

Posteriormente agruparía, produciendo lo siguiente, con los campos solicitados:

Page 12: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 11 —

Art Nom Vendido A02 Pantalón 90 A04 Pañuelo 100 A05 Cinto 70 A06 Zapatos 90

Finalmente ordenaría por NOM y obtendría el cursor definitivo: Art Nom Vendido A05 Cinto 70 A02 Pantalón 90 A04 Pañuelo 100 A06 Zapatos 90

Ejercicio 11 Cree CON11 para calcular la cantidad de unidades totales vendidas de cada artículo. Ordene la salida por nombre de artículo. 1. La consulta a crear es similar a CON10, de modo que créela a partir de ella y agréguela al proyecto. 2. Lo que varía con respecto a CON10 es que no debe calcular el importe total de ventas por artículo,

sino el total de unidades vendidas de cada uno. Elimine el campo seleccionado SUM(LINFAC.CAN * LINFAC.PRE) AS VENDIDO, reemplazándolo por SUM(LINFAC.CAN) AS UNIDADES.

3. Ejecute y guarde la consulta. Ejercicio 12 Cree CON12 para que muestre los campos FAC, FEC, CLI de ENCFAC y el total de cada factura. 1. Cree una nueva consulta. Agregue las tablas ENCFAC y LINFAC, combinándolas internamente por el

campo FAC. 2. Agregue como seleccionados los campos FAC, FEC y CLI. Agregue también la expresión

SUM(LINFAC.PRE * LINFAC.CAN) AS IMPORTE. 3. Agrupe por ENCFAC.FAC. 4. Guarde y ejecute la consulta. Ejercicio 13 En una nueva consulta CON13, realice lo mismo que en CON12, pero agregando el nombre de cada cliente, que debe tomar de la tabla CLI. 1. Cree CON13 a partir de CON12. Agregue CON12 al proyecto y modifíquela. 2. Agregue la tabla CLI. Acepte en principio la combinación interna ENCFAC.CLI con CLI.CLI. Veremos

que esto produce errores, porque cuando hay más de dos tablas en el panel de entorno, se debe observar una regla.

3. Agregue CLI.NOM a campos seleccionados. Reubique los campos, para que el código de cliente salga junto al nombre.

4. Guarde y ejecute la consulta. Aunque el código de cliente varía, siempre aparece el mismo nombre de cliente. Obviamente hay un error, debido a las combinaciones. Active la ficha COMBINACIÓN y verá lo siguiente:

Page 13: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 12 —

Tipo Nombre de campo No Criterios Valor Lógico Inner Join Encfac.fac = Linfac.fac Inner Join Encfac.cli = Cli.cli

Hay dos líneas, una por combinación. Cada botón abre el diálogo CONDICIÓN DE COMBINACIÓN pa-ra la combinación correspondiente, permitiendo modificarla. En TIPO hay una lista desplegable para cada combinación, para elegir su tipo, que se ofrecen en inglés: Inner Join quiere decir combina-ción interna. En NOMBRE DE CAMPO se define la tabla izquierda y su campo de combinación. En CRITERIOS, en principio, debe definir el operador =, que es el ofrecido inicialmente. En VALOR se de-fine la tabla derecha con su campo. NO niega el criterio, que por lo dicho, en principio no se usa, pues negaría el =, dando distinto. LÓGICO sirve para elegir los operadores AND y OR, permitiendo lograr combinaciones compuestas. Cuando hay varias tablas, la que está a la derecha en una combinación debe estar a la izquierda en la combinación siguiente. Esta regla no se ha observado y es lo que produce el error. El esque-ma de combinaciones, aplicando la regla, debe ser el siguiente:

Tipo Nombre de campo No Criterios Valor Lógico Inner Join Cli.cli = Encfac.cli Inner Join Encfac.fac = Linfac.fac

Otra forma de combinar las tablas, también correcta, es: Tipo Nombre de campo No Criterios Valor Lógico

Inner Join Linfac.fac = Encfac.fac Inner Join Encfac.cli = Cli.cli

Usemos el primer equema. Hay varias formas de corregir el error. Una es seleccionar cada línea de combinación en el panel de entorno, pulsar la tecla SUPRIMIR y trazarla de nuevo, arrastrando del campo de la tabla izquierda al campo de la tabla derecha. Recuerde que izquierda y derecha no se refieren a cómo están dispuestos los cursores en el panel, sino a las tablas de partida y llegada, respectivamente. Para no confundirse, puede mover los cursores para que visualmente queden a la izquierda y derecha, de acuerdo al arrastre. Otra forma es eliminar cada línea en la ficha COMBINACIÓN, ubicándose en ella y pulsando el botón QUITAR. Posteriormente se puede construir cada combinación definiendo su tipo y las tablas y cam-pos izquierdos y derechos. Otra forma es pulsar el botón de cada combinación y tratar de modificarla en el diálogo CONDICIÓN DE COMBINACIÓN. Esto no siempre es posible, porque como la condición ya está definida y se la quiere editar, las posibilidades de tablas izquierdas son todas las que no estén como tabla derecha, porque una tabla no se puede combinar consigo misma. Lo mismo sucede con la tabla derecha. Pero si fuera posible usar este diálogo, quizás resulte que las combinaciones están co-rrectas pero mal ubicadas, infringiendo la regla. Queda todavía el recurso de intercambiarlas, arras-trándolas hacia arriba o hacia abajo con el botón que aparece a la izquierda de cada combinación. Use la primera o segunda formas para corregir el error y lograr el primer esquema.

5. Guarde y ejecute la consulta. Ejercicio 14 Cree Con14 para que muestre el nombre de los clientes y el total comprado por cada uno. Ordene por nombre. 1. Cree una nueva consulta. Agregue las tablas CLI, ENCFAC y LINFAC. Dado que las combinaciones

propuestas son correctas, acéptelas.

Page 14: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 13 —

2. Agregue como campo de salida CLI.NOM y SUM(LINFAC.CAN * LINFAC.PRE) AS COMPRADO. 3. Agrupe por CLI.CLI. 4. Ordene por CLI.NOM. 5. Guarde y ejecute la consulta. Ejercicio 15 Cree CON15 para obtener lo comprado por cada cliente en cada factura. Se debe ordenar por nombre de cliente y número de factura. 1. Cree una nueva consulta. Agregue las tablas CLI, ENCFAC y LINFAC. Acepte las combinaciones pro-

puestas, porque son correctas. 2. Agregue como salida CLI.NOM, ENCFAC.FAC y SUM(LINFAC.CAN * LINFAC.PRE) AS COMPRADO. 3. Agrupe por CLI.CLI y ENCFAC.FAC. 4. Ordene por CLI.NOM y ENCFAC.FAC. 5. Guarde y ejecute la consulta. Ejercicio 16 Cree CON16 para obtener el total de ventas en cada provincia. Ordene por nombre de provincia. 1. Cree una nueva consulta. Agregue las tablas PROV, CLI, ENCFAC y LINFAC. Las condiciones de

combinación pueden ser como indica cualquiera de los siguientes esquemas: Prov.prv = Cli.prv Linfac.fac = Encfac.fac Cli.cli = Encfac.cli Encfac.cli = Cli.cli Encfac.fac = Linfac.fac Cli.prv = Prov.prv

¿Para qué usar cuatro tablas, si cuando la información a obtener proviene solamente de dos? Por-que, para poder llegar de PROV a LINFAC, las tablas con la información necesitada, debemos usar como "puentes" las tablas CLI y ENCFAC.

2. Agregue como salida PROV.NOM y SUM(LINFAC.PRE*LINFAC.CAN) AS VENTAS. 3. Agrupe por PROV.PRV. También podría agrupar por PROV.NOM, porque ningún nombre de provincia

se repite. 4. Ordene por PROV.NOM. 5. Ejecute y guarde la consulta. Ejercicio 17 Cree CON17 para que calcule cuántas compras ha hecho cada cliente, sabiendo que cada factura es una compra. Incluya el nombre del cliente y ordene la salida por este concepto. 1. Cree una nueva consulta. Agregue las tablas ENCFAC y CLI, combiándolas por el campo CLI. 2. Agregue como salida el campo CLI.NOM y la expresión COUNT(ENCFAC.FAC) AS FACTURAS.

La función COUNT( ) suma 1 por cada factura de cada cliente, obteniendo cuántas son. 3. Agrupe por CLI.CLI o por ENCFAC.CLI. 4. Ordene por CLI.NOM. 5. Guarde y ejecute la consulta.

Page 15: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 14 —

Ejercicio 18 Cree CON18 para saber cuánto ha vendido cada vendedor de cada artículo. 1. Cree una nueva consulta. Agregue las tablas VEN, ENCFAC, LINFAC y ART. Las combinaciones pue-

den ser cualquiera de los dos esquemas siguientes: Ven.ven = Encfac.ven Art.art = Linfac.art Encfac.fac = Linfac.fac Linfac.fac = Encfac.fac Linfac.art = Art.art Encfac.ven = Ven.ven

2. Agregue como campos de salida las expresiones VEN.NOM AS VENDEDOR, ART.NOM AS ARTÍCULO y SUM(LINFAC.CAN*LINFAC.PRE) AS PRODUCCIÓN.

3. Dado que conviene no usar los nombres para agrupar, debe usar los campos VEN y ART. Tiene va-rias posibilidades:

Primer campo (arriba) Segundo campo (abajo) Ven.ven Linfac.art Ven.ven Art.art Encfac.ven Linfac.art Encfac.ven Art.art Linfac.art Ven.ven Linfac.art Encfac.ven Art.art Ven.ven Art.art Encfac.ven

Cualquiera de las posibilidades anteriores es válida, porque se producirá un grupo por cada valor diferente de ambos componentes. El orden final de los registros se hará por los nombres de ven-dedor y de artículo.

4. Ordene por nombre de vendedor y nombre de artículo. 5. Guarde y ejecute la consulta. Ejercicio 19 Se quiere una consulta CON19 que calcule el total de ventas de cada vendedor a cada cliente. Debe dar el nombre del vendedor, el nombre del cliente y el total. El esquema de combinaciones desde un punto de vista lógica sería:

Ven.ven = Encfac.ven Encfac.fac = Linfac.fac Encfac.cli = Cli.cli

Esquemáticamente, los cursores y combinaciones se verían así (se muestran los nombres de los curso-res y de los campos de combinación):

Encfac Linfac Ven Fac Fac Ven Ven Cli Cli Cli

Este entorno es dificultoso de establecer, porque habría que eliminar las combinaciones y volverlas a trazar por arrastre. Lo que es peor, la consulta no funcionaría, debido a que no se cumple la regla: la tabla derecha de la segunda combinación no es la tabla izquierda de la tercera. El problema se soluciona si ENCFAC se agregar otra vez al entorno. Una tabla se puede agregar varias veces, sin confundir a SQL, porque les da un alias diferente: la primera vez el alias será igual al nombre

Page 16: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 15 —

de la tabla, ENCFAC; pero en adelante el alias será ENCFAC_A, ENCFAC_B, etc. El esquema de combina-ción correcto, entonces, es:

Ven.ven = Encfac.ven Encfac.fac = Linfac.fac Linfac.fac = Encfac_a.fac Encfac_a.cli = Cli.cli

Los cursores quedarán como las perlas de un collar, unidos por una cadena de combinaciones: Ven Encfac Linfac Encfac_a Cli Ven Ven Cli Cli Fac Fac Fac

La disposición generalizada del dibujo expresa la regla, que llamamos regla de la cadena. La solución indicada funciona en este caso, porque la tercera combinación es 1 – 1: cada valor de fac-tura en los registros de LINFAC tiene un solo registro correspondiente en ENCFAC_A. Si fuera una combi-nación 1 – N, SQL no la podría manejar adecuadamente y produciría resultados erróneos, por lo que habría que buscar otra solución. 1. Cree una nueva consulta. Agregue las tablas y combinaciones del último esquema. 2. Seleccione como campos las expresiones VEN.NOM AS VENDEDOR, CLI.NOM AS CLIENTE y SUM(

LINFAC.PRE * LINFAC.CAN ) AS IMPORTE. 3. Agrupe por VEN.VEN y CLI.CLI o por CLI.CLI y VEN.VEN. 4. Elimine en la ficha CAMPOS los campos seleccionados VEN.VEN y CLI.CLI, para que no aparezcan en

el cursor de salida. 5. Ordene por VEN.NOM y CLI.NOM. 6. Guarde la consulta y ejecútela. Ejercicio 20 Se quiere una consulta que calcule el total vendido de cada artículo, por cada vendedor, a cada cliente. Un esquema de combinaciones, lógico pero complicado e ineficaz, sería:

Ven.ven = Encfac.ven Encfac.fac = Linfac.fac Linfac.fac = Art.art Art.art = Linfac_a.art Linfac_a.fac = Encfac_a.fac Encfac_a.cli = Cli.cli

Este esquema produce resultados erróneos, porque se producen combinaciones 1 – N incorrectas. Veamos dónde está el error. Sea que el artículo A01 se ha vendido en las facturas 15 y 28, como único artículo en cada factura. La factura 15 tiene vendedor 8 y cliente 14. La factura 28 tiene vendedor 55 y cliente 49. Esto queda más claro en el siguiente cuadro:

Factura Vendedor Cliente Único 15 8 14 A01 28 55 49 A01

Cuando se procesa la factura 15 del vendedor 8 se producen las siguientes combinaciones:

Page 17: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 16 —

Ven Encfac Linfac Art Linfac_a Encfac_a Cli Ven Ven Fac Fac Art Art Art Fac Fac Cli Cli

8 8 15 15 A01 A01 A01 15 15 14 14 8 8 15 15 A01 A01 A01 28 28 49 49

Al combinar ART con LINFAC_A, SQL combina el artículo A01 de ART con cada aparición de tal código en LINFAC_A, olvidando que debe pertenecer al vendedor 8 y a la factura 15. Esto produce cálculos erróneos, pues se atribuye a la factura 15 el importe de la factura 28. Para solucionar este problema, conviene dividir el problema en dos consultas. La primera, que llama-remos CON20A, producirá una tabla de salida con los campos VEN.NOM, CLI.CLI, ART.NOM y SUM(LINFAC.CAN * LINFAC.PRE) AS IMPORTE. La segunda, que llamaremos CON20B, tendrá como entrada la tabla resultante de CON20A y la tabla CLI, dando como resultado los campos anteriores, pero reem-plazanco CLI.CLI con CLI.NOM. Cuando se presentan combinaciones similares a las explicadas, más que analizar las causas de error conviene dividir el problema en dos o más consultas. Veremos más tarde que las vistas son más ade-cuadas que las consultas para estos casos. Creemos primero la consulta CON20A. 1. Cree una consulta. Agregue las tablas VEN, ENCFAC, LINFAC y ART. Combínelas como indican las

tres primeras líneas del esquema anterior, es decir: Ven.ven = Encfac.ven Encfac.fac = Linfac.fac Linfac.fac = Art.art

2. Agregue como salida los campos VEN.NOM AS VENDEDOR, ENCFAC.CLI, ART.NOM AS ARTÍCULO y SUM(LINFAC.CAN * LINFAC.PRE) AS IMPORTE.

3. Agrupe por VEN.VEN, ENCFAC.CLI y ART.ART. 4. Ejecute la consulta para ver los resultados en la ventana EXAMINAR. 5. En el menú CONSULTA, seleccione DESTINO DE LA CONSULTA. 6. En el diálogo DESTINO DE LA CONSULTA pulse el botón TABLA. Aparece el campo NOMBRE DE TABLA.

Escriba CON20A y pulse ACEPTAR. 7. Ejecute la consulta para generar la tabla CON20A y guarde la consulta como CON20A.

Por defecto, las consultas producen un cursor que se ve en la ventana EXAMINAR. Ese cursor tiene un nombre que calcula SQL a partir del reloj del sistema, de modo que nunca obtiene dos nombres iguales. Los cursores son similares a las tablas en estructura, pero no admiten índices y son des-truidos automáticamente cuando se da cualquier comando que cierre las tablas abiertas o cuando se sale de VFP. Tienen extensión TMP, abreviatura de temporal. Puede suceder que el usuario necesite que la consulta no produzca ese cursor, sino que cree un cursor o una tabla con los nombres que él les dé. Las consultas permiten tales salidas, definiendo los destinos CURSOR y TABLA, que solicitan un nombre. Estos cursores o tablas no van a la ventana EXAMINAR, pero quedan abiertos. Al darse un comando para cerrar las tablas, lo cursores, como se ha dicho, desaparecen, pero las tablas quedan en disco. La tabla que produce una ejecución de la consulta es generada nuevamente por otra ejecución, sin que se advierta que ya existe.

Creemos finalmente la consulta CON20B. 1. Cree una consulta. Agregue las tablas CON20A y CLI. Combine por el campo CLI.

Page 18: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 17 —

2. Agregue como salida los campos CON20A.VENDEDOR,CLI.NOM AS CLIENTE, CON20A.ARTÍCULO y CON20A.IMPORTE.

3. Ordene por VENDEDOR, CLIENTE y ARTÍCULO. 4. Guarde la consulta como CON20B y ejecútela. Dividir el problema ha simplificado la tarea. Pero trabajar con una tabla generada por una consulta tiene inconvenientes. Primero, para tener una versión actualizada de la tabla CON20A, debemos ejecutar la consulta CON20A antes de ejecutar CON20B. Si olvidamos hacerlo, SQL buscará la tabla existente, lo cual puede dar resultados desactualizados. Segundo, si eliminamos la tabla CON20A para ganar espa-cio, necesariamente deberemos ejecutar la consulta CON20A antes de CON20B, que usa esa tabla como entrada. Veremos más adelante que estos inconvenientes se evitan con las vistas. Ejercicio 21 Hemos visto que las consultas son muy versátiles para combinar tablas y obtener gran variedad de re-sultados. Una pregunta que usted puede plantear es si los formularios y los informes pueden aprove-char el producto de las consultas. La respuesta es afirmativa. Para ilustrar someramente esta respuesta vamos a desarrollar algunos ejemplos. Vamos a crear un formulario que contenga un GRID cuyo RECORDSOURCE sea el cursor resultante de una consulta. Los campos del Grid serán los campos del cursor, para lo cual debemos crear primero la consulta. Esos campos serán código de cliente, número de factura y total general de factura. Primero creemos la consulta. 1. Cree una consulta. Agregue las tablas ENCFAC y LINFAC, combinadas por el campo FAC. 2. Agregue como salida ENCFAC.CLI, ENCFAC.FAC y SUM(LINFAC.CAN * LINFAC.PRE) AS IMPORTE. 3. Agrupe por ENCFAC.CLI y ENCFAC.FAC. 4. Ejecute la consulta, para ver el resultado en le ventana EXAMINAR. 5. Elija CURSOR como destino de la consulta y llame CON21 a ese cursor. 6. Guarde la consulta como CON21. 7. Ejecute CON21. Ahora no aparece el resultado en la ventana EXAMINAR. El resultado se ha enviado

al cursor CON21, que debe todavía estar abierto. 8. Compruebe que el cursor está abierto: abra la ventana SESIÓN DE DATOS y observe que en el listado

ALIAS figura Con21. Seleccione el cursor y pulse CERRAR. Salga de SESIÓN DE DATOS con ESC. Continuemos ahora con el formulario. 9. Cree un formulario. 10. Agregue un GRID. Configure las siguientes propiedades:

Objeto Propiedad Valor Grid RecordSourceType 3 – Consulta (.QPR) RecorSource Con21 ColumnCount 3 DeleteMark .F. – Falso ScrollBars 2 - Vertical Width 195 Column1 ControlSource Cli Width 50

Page 19: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 18 —

Header Caption Cliente Column2 ControlSource Fac Width 50 Header Caption Factura Column3 ControlSource Importe Width 60 Header Caption Importe

El valor 3 – CONSULTA (.QPR) de RECORDSOURCETYPE indica que se va a usar como entrada el re-sultado de una consulta. El nombre de ella se escribe en RECORDSOURCE. El valor CONTROLSOURCE de cada columna es cada campo del cursor CON21 generado por la consulta. Oserve que los cam-pos definidos en CONTROLSOURCE no están prefijados con el alias del cursor. Hemos observado que, colocándoselo, a veces se producen resultados incorrectos.

11. Agregue un botón de comando, con CAPTION y NAME SALIR. 12. Pulse doble click en el botón SALIR y en el evento CLICK de ese objeto escriba:

close tables all thisform.release

13. Guarde el formulario con el nombre CON21 y ejecútelo. Hemos introducido el botón SALIR no sólo para que sea más fácil de pulsar que el botón de cierre del formulario, sino para que cierre las tablas y cursores abiertos con el comando CLOSE TABLES ALL. Aunque es innecesario cerrar el cursor CON21, lo hemos hecho para que compruebe, luego de eje-cutar el formulario, que ya no aparece en la ventana SESIÓN DE DATOS.

Ejercicio 22 El sencillo formulario CON21 es poco práctico, porque el GRID no muestra el nombre de los clientes, si-no los códigos. Por otro lado, el GRID muestra todos los códigos de cliente, y no uno en particular que nos interese. Sería preferible un formulario que presente en un LISTBOX, COMBOBOX o GRID los nombres de los clien-tes y sus códigos, en orden alfabético, tomándolos de la tabla CLI. Elegido un cliente específico, otro GRID, mostraría todas sus facturas, con las fechas e importes. Podríamos usar una consulta para cons-truir un cursor con los campos a mostrar en cada columna de este segundo GRID, más el campo CLI, para filtrar el cliente a mostrar. Creemos primero la consulta. 1. Cree una consulta. Agregue las tablas ENCFAC y LINFAC. 2. Agregue como salida ENCFAC.FAC, ENCFAC.FEC, SUM(LINFAC.CAN * LINFAC.PRE) AS IMPORTE y

ENCFAC.CLI. 3. Agrupe por ENCFAC.CLI y ENCFAC.FAC. 4. Ejecute la consulta para controlar los resultados en la ventana EXAMINAR. 5. Envíe el resultado de la consulta al cursor CON22. 6. Guarde la consulta como CON22. Ahora creemos el formulario. 1. Cree un formulario, que se llamará CON22. Agréguele un LISTBOX, un GRID y un botón de comando. 2. En el entorno de datos agregue la tabla CLI. Establezca la propiedad ORDER al índice NOM. 3. Defina las siguientes propiedades:

Page 20: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 19 —

Objeto Propiedad Valor ListBox ColumnWidths 150,0 ColumnCount 2 RowSource Cli.Nom,Cli RowSourceType 6 - Campos Width 178 Grid RecordSource Con22 RecordSourceType 3 – Consulta (.QPR) ColumnCount 2 DeleteMark .F. - Falso ScrollBars 2 - Vertical Width 248 Column1 ControlSource Fac Width 60 Header Caption Factura Column2 ControlSource Fec Width 75 Header Caption Fecha Column3 ControlSource Importe InputMask 999,999.99 Width 80 Header Caption Importe CommandButton Caption Salir Name Salir

Puede preguntarse por qué no definir las propiedades que subordinarían el GRID a la tabla CLI. El problema radica en que no se puede definir la propiedad CHILDORDER, porque siendo el cursor CON22 de lectura, no se puede crear un índice para él. Debemos, en consecuencia, apelar a un filtro de registros sobre el cursor. Este filtro se aplicará ca-da vez que se elija un cliente en el LISTBOX, en el evento CLICK de este objeto.

4. En el evento CLICK del LISTBOX, escriba: select con22 set filter to cli=cli.cli go top thisform.grid1.refresh

5. En el evento CLICK del botón SALIR, escriba: close tables all thisform.release

6. Ejecute el formulario. Guárdelo como CON22. Ejercicio 23 Veamos otra forma de realizar lo mismo que hace CON22, pero sin definir el entorno de datos y usando comandos para crear el cursor CON23 y abrir la tabla CLI. 1. Cree el formulario CON23 a partir del formulario CON22. 2. Abra el entorno de datos y elimine el cursor de la tabla CLI. 3. En el GRID, cambie el valor de la propiedad RECORDSOURCETYPE por 1 – ALIAS y el de la propiedad

RECORDSOURCE por CON23.

Page 21: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 20 —

4. En el evento LOAD del formulario, escriba: close tables all use cli in 0 order nom noupdate

En el menú VENTANA elija la ventana ADMINISTRADOR DE PROYECTOS – FAC. Seleccione la consulta CON22 y pulse el botón MODIFICAR. En el DISEÑADOR DE CONSULTAS pulse el botón secundario y elija VER SQL. Se abre la ventana CON22.QPR [SÓLO LECTURA], donde aparece el comando SELECT pro-ducido por lo definido en el diseñador. Seleccione todo el texto y cópielo. Cierre la ventana y el di-señador con ESC. Vuelva a la ventana CÓDIGO del evento LOAD del formulario. Al final del texto pe-gue el comando Select de SQL. Corrija la última línea, reemplazando CON22 por CON23. El texto definitivo debe quedar como sigue: close tables all use cli in 0 order nom noupdate SELECT Encfac.fac, Encfac.fec, SUM(Linfac.can*Linfac.pre) AS importe,; Encfac.cli; FROM fac!encfac INNER JOIN fac!linfac ; ON Encfac.fac = Linfac.fac; GROUP BY Encfac.cli, Encfac.fac; INTO CURSOR con23

5. En el evento CLICK del LISTBOX, modifique la primera línea, cambiando CON22 por CON23. 6. Ejecute el formulario.

Hemos creado la consulta CON23 sin necesidad de usar el diseñador correspondiente. Esto se de-be a que el diseñador de consultas produce en definitiva un comando SELECT de SQL, que es lo esencial. El diseñador es un recurso intermedio que facilita la construcción de SELECT, pero SELECT se puede escribir directamente. En este ejemplo, hemos copiado el SELECT correcto de la consulta CON22, lo hemos pegado donde nos hace falta y lo hemos corregido ligeramente.

Ejercicio 24 El formulario CON23 muestra los importes comprados en cada factura del cliente elegido en el LISTBOX, pero no el total general de esos importes. Este podría aparecer al pie del GRID, en un TEXTBOX. Para calcularlo, podríamos duplicar el comando SELECT, con leves modificaciones. El primer SELECT sería igual al original, cambiando el nombre del cursor a CON24A. El segundo SELECT produciría el cursor CON24B, que debería agrupar solamente por cliente. 1. Cree CON24 a partir de CON23. 2. Corriga la propiedad RECORDSOURCE de GRID1 por CON24A. 3. Entre a la ventana CÓDIGO del evento LOAD del formulario, seleccione todo el comando SELECT, có-

pielo y péguelo al final. Corrija las líneas que se ven en negrita en el texto definitivo siguiente: close tables all use cli in 0 order nom noupdate SELECT Encfac.fac, Encfac.fec, SUM(Linfac.pre*Linfac.can) AS importe,; Encfac.cli; FROM fac!encfac INNER JOIN fac!linfac ; ON Encfac.fac = Linfac.fac; GROUP BY Encfac.cli, Encfac.fac; INTO CURSOR con24a SELECT Encfac.cli, SUM(Linfac.pre*Linfac.can) AS general; FROM fac!encfac INNER JOIN fac!linfac ; ON Encfac.fac = Linfac.fac; GROUP BY Encfac.cli; INTO CURSOR con24b

4. Agregue un LABEL y un TEXTBOX al pie del GRID. Modifique las siguiente propiedades:

Page 22: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 21 —

Objeto Propiedad Valor Label Caption Total general AutoSize .T. – Verdadero InputMask 999,999,999.99 Width 100 TextBox ControlSource con24b.general Name general

5. Modifique el evento CLICK del LISTBOX, para que quede como sigue: select con24a set filter to cli=cli.cli go top thisform.grid1.refresh select con24b set filter to cli=cli.cli go top thisform.general.refresh

6. Ejecute el formulario.

Vistas Ejercicio 1 Cree la vista VIS1 para que produzca un cursor con solamente los artículos cuyo código de artículo (campo ART) se indique al momento de la ejecución. Este ejercicio es similar al Ejercicio 2 de Consultas. Cada vez que se examina, CON2 da salida a los ar-tículos cuyo nombre comienza con C. Lo mismo se puede hacer en las vistas, pero para darles mayor flexibilidad se las puede construir con parámetros. Los parámetros son cualquier nombre válido prece-dido por un signo ? que se usan para construir filtros sobre los registros de entrada y de salida. Se co-locan en la columna EJEMPLO de la ficha FILTRO y del diálogo CONDICIONES. Cada vez que se examina una vista que posee parámetros, antes de comenzar a trabajar, SQL pide un valor específico para cada parámetro. 1. Ubíquese en la categoría VISTAS LOCALES y pulse el botón NUEVO. Esto abre el DISEÑADOR DE

VISTAS, que es muy parecido al diseñador de consultas, aunque hay algunas diferencias. 2. Agregue la tabla ART. En la ficha CAMPOS agregue los campos ART.ART y ART.NOM. 3. Seleccione la ficha FILTRO. En NOMBRE DE CAMPO elija ART.ART. En CRITERIOS elija el operador = y

en EJEMPLO escriba ?INICIAL. 4. Guarde la consulta con CTRL + S, llamándola VIS1. 5. Examínela con EJECUTAR CONSULTA del menú secundario. Aparece el diálogo PARÁMETRO DE VISTA,

con el texto Escriba un valor para Inicial. En el campo en blanco escriba "C". Pulse ACEPTAR. Ahora se abre la ventana EXAMINAR, con los registros cuyo nombre comienza con C. Salga con ESC.

6. Vuelva a examinar la vista, pero ahora escriba el valor A para el parámetro. El proceso se repite, pero los registros mostrados comienzan ahora con A.

7. Salga del diseñador. VIS1 aparece registrada en la categoría VISTAS LOCALES. A diferencia de las consultas, las vistas no se guardan en archivos por separado, sino en la base de datos actual. Las consultas pueden agregarse a un proyecto. También pueden quitarse de él,

Page 23: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 22 —

permaneciendo como archivos independientes. Las vistas no pueden agregarse a una base de da-tos, sino crearse en ellas; si se quitan, se eliminan definitivamente. Las vistas tienen como destino único un cursor que se ve en la ventana EXAMINAR. SQL crea el nombre de este cursor desde el reloj de la computadora. A diferencia de las consultas, el cursor es de lectura y escritura, es decir, permite modificar campos, agregar nuevos registros o marcarlos pa-ra destruir. Para probar esta propiedad, examine la vista otra vez. De lo dicho en el párrafo anterior, surge inmediatamente la pregunta sobre el sentido de las altas, bajas y cambios en un cursor que va a desaparecer al dar un comando que cierre tablas. La res-puesta es que existe la posibilidad de mandar a las tablas de entrada las modificaciones hechas en el cursor. Veremos este tema más adelante. Al reconocer que INICIAL es un parámetro, porque va precedido por un signo de pregunta, SQL pide el valor que le queremos dar en el diálogo PARÁMETRO DE VISTA. Para que nos indique cuál es el ti-po de datos del parámetro, debemos hacer lo que dice el punto siguiente.

8. Para indicar el tipo de datos del parámetro, emita el comando CONSULTA – PARÁMETROS DE VISTA. Esto abre el diálogo de igual nombre. En la columna NOMBRE escriba INICIAL. En la columna TIPO seleccione CARÁCTER.

9. Examine la vista. Ahora el diálogo PARÁMETRO DE VISTA es más específico, pues dice Escriba un valor de tipo carácter para Inicial. Esta especificación es más útil, porque nos orienta sobre si debemos introducir núme-ros, caracteres, fechas, etc. Cuando una vista usa muchos parámetros, habrá uno de estos diálo-gos para cada uno, donde la aclaración del tipo de datos facilita la tarea.

10. Guarde los cambios. Note que, al estar activo el diseñador de vistas, no aparece ningún menú VISTA, sino el ya conocido CONSULTA. Del mismo modo, para producir la vista, no hay una opción EJECUTAR VISTA, sino la ya conocida EJECUTAR CONSULTA.

Ejercicio 2 Cree la vista VIS2 para que muestre las facturas de un vendedor y un cliente parametrizados. Trabaje solamente con la tabla ENCFAC. Ordene la salida por factura. 1. Cree una vista. Agregue la tabla ENCFAC y todos sus campos. 2. En la ficha FILTRO, escriba los filtros siguientes:

Encfac.ven = ?Vendedor Encfac.cli = ?Cliente

3. En CONSULTA – PARÁMETROS DE VISTA especifique que VENDEDOR y CLIENTE son numéricos. 4. En ORDENAR POR seleccione el campo ENCFAC.FAC. 5. Guarde y examine la vista. Aparecen dos diálogos PARÁMETRO DE VISTA, uno por parámetro. 6. En el diseñador, con el botón secundario pulse VER SQL. Aunque usted no lo ha definido, el opera-

dor que une ambos filtros es AND, por ser el operador por defecto. Ello se ve en la cláusula WHERE del comando SELECT, donde dice:

WHERE Encfac.cli = ?Cliente; AND Encfac.ven = ?Vendedor

Ejercicio 3 Cree la vista VIS3, similar a VIS2, pero que agregue el importe total vendido por el vendedor al cliente. Trabaje solamente con las tablas ENCFAC y LINFAC. Ordene la salida por factura.

Page 24: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 23 —

1. Cree VIS2 a partir de VIS1. 2. Agregue la tabla LINFAC, combinándola con ENCFAC por el campo FAC. 3. Agregue SUM(LINFAC.CAN * LINFAC.PRE) AS TOTAL como campo de salida. 4. Guarde y examine la vista. Note que no ha hecho falta agrupar por vendedor y cliente, porque los filtros han reducido el universo de registros a los de un solo vendedor y un solo cliente. Ejercicio 4 Cree la vista VIS4 que muestre los campos ART, NOM y PRE de la tabla ART y permita actualizar indirec-tamente el campo PRE de tal tabla. Con indirectamente queremos decir que, si cambiamos el campo PRE del cursor de salida, ese cambio modifique el valor PRE de la tabla ART. ¿En qué registro de la ta-bla ART se producirá ese cambio indirecto? Pues exactamente en el registro que origina el registro que modificamos en el cursor de salida. Primero, vamos a corregir el campo PRE de la tabla ART, exigiendo mediante la regla de validación que no pueda ser nulo ni negativo. Si esto sucede, queremos que VFP dé el mensaje "Precio debe contener un valor positivo". Esta modificación la introducimos para explicar una característica de las vistas. 1. En el ADMINISTRADOR DE PROYECTOS elija la tabla ART y pulse el botón MODIFICAR. 2. En la ficha CAMPOS del DISEÑADOR DE TABLAS elija el campo PRE. 3. En REGLA de validación escriba la expresión PRE > 0. 4. En MENSAJE de validación escriba "PRECIO DEBE CONTENER UN VALOR POSITIVO". 5. Pulse ACEPTAR. 6. Examine la tabla ART. Ubíquese en algún campo PRE y escriba 0. Al tratar de salir del campo, apa-

recerá el mensaje de error. Pulse el botón VOLVER, para reponer el valor anterior. Este experimento ha servido para ver cómo funciona una regla de validación de campo.

Ahora cree la vista VIS4. 1. Agregue la tabla ART al panel de entorno. 2. Agregue todos los campos a CAMPOS SELECCIONADOS. 3. Seleccione PRE en CAMPOS SELECCIONADOS y pulse el botón PROPIEDADES. Esto abre el diálogo

PROPIEDADES DEL CAMPO DE LA VISTA. Dado que queremos que el campo PRE pueda ser modificado en el cursor de salida, mandando el nuevo valor a la tabla ART, podría suceder que en el cursor reemplacemos un precio por un valor nulo o negativo. Pero el cursor funcionaría incorrectamente si aceptara esto, ya que estaría en desacuerdo con la tabla. Lo correcto sería que el cursor tuviera una regla y un mensaje de valida-ción del campo PRE, similares a los que tiene el campo PRE de la tabla ART. Para eso, precisamente, sirve el diálogo PROPIEDADES DEL CAMPO DE LA VISTA. Funcionalmente es exactamente igual a las posibilidades que se ven en la ficha CAMPOS de una tabla base, debajo de las definiciones de campos, tipos, anchos, etc. En el DISEÑADOR DE TABLAS elegimos el campo en la columna NOMBRE. Como en el diálogo PROPIEDADES DEL CAMPO DE LA VISTA no aparece esa colum-na, la forma de elegirlo es abriendo la lista desplegable CAMPO y seleccionando el deseado.

4. Abra la lista CAMPO y elija ART.PRE. 5. En REGLA escriba PRE > 0. 6. En MENSAJE escriba "PRECIO DEBE CONTENER UN VALOR POSITIVO".

Page 25: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 24 —

Ahora entenderá para qué modificamos inicialmente la tabla ART, introduciendo una regla y un mensaje de validación para el campo PRE. No sería congruente que, en la tabla, el campo PRE es-tuviera sujeto a una regla de validación y una vista permitiera modificar indirectamente su conteni-do sin observar tal regla. Como los cursores de salida permiten modificar cualquier campo, nos queda definir que sólo las modificaciones del campo PRE del cursor se envíen al campo PRE de la tabla ART.

7. Seleccione la ficha CRITERIOS DE ACTUALIZACIÓN del DISEÑADOR DE VISTAS. En la lista desplegable TABLA aparece ART. Esta lista muestra las tablas del panel de entorno. En este ejercicio, sólo trabajamos con la tabla ART, por lo que no aparece ninguna otra.

El cuadro central está dividido en tres columnas, una encabezada por un ícono , otra por un íco-no y la última llamada NOMBRE DEL CAMPO. En esta última columna se ven los campos del cur-sor, uno por línea. La columna Llave muestra una tilde en la línea de ART. Esto indica que este campo se va a usar como clave para buscar en la tabla de entrada ART el registro cuyo campo PRE debe ser modificado con el valor modificado en el campo PRE del cursor. Que sea clave quiere decir que identifique el registro a modificar de modo inequívoco. El campo ART es precisamente el campo clave de la tabla ART, que nos ha permitido construir el índice principal de esa tabla. Nótese que, sin hacer nosotros nada, este campo apareció con tilde en la columna Llave. Esto se debe a que hay un índice principal por él. Si en lugar de principal fue-ra un índice candidato, VFP no supone que es clave. Esta es una diferencia de funcionamiento en-tre índices principales e índices candidatos. La columna Lápiz muestra una tilde en la línea de NOM y otra en la línea de PRE. Esto indica que las modificaciones en los valos de estos campos se van a enviar a la tabla. En principio, SQL su-pone que todos los campos, excepto los campos clave, van a ser de este tipo. En nuestro caso, como sólo queremos que esto suceda con el campo PRE, deberemos destildar el campo NOM. Nótese que la línea de ART no tiene tilde en la columna Lápiz. Esto se debe a una actitud prudente de SQL. Aunque los cambios de clave se pueden enviar a la tabla, esto puede traer varios proble-mas que necesitan ser tratados adecuadamente. Como es un tema complejo, nos limitamos a re-comendar seguir con la prudencia de SQL, es decir, nunca hacer actualizables los campos clave. Si por equivocación destildamos campos clave y no recordamos cuáles son, podemos recurrir al botón RESTABLECER CLAVES, que vuelve a marcarlos, teniendo en cuenta que forman la expresión de índices principales. Si destildamos campos actualizables y queremos volver a marcarlos todos, el botón ACTUALIZAR TODOS realiza esta tarea. El hecho de marcar algunos o todos los campos como actualizables no los hace inmediatamente tales, sino que es necesario poner en vigencia esta modalidad. Para ello se usa la casilla de verifi-cación ENVIAR ACTUALIZACIONES (SQL). La porción derecha de la ficha CRITERIOS DE ACTUALIZACIÓN, que incluye los rubros LA CLÁUSULA SQL WHERE INCLUYE y ACTUALIZAR USANDO no nos interesan, por referirse principalmente a vistas remotas.

8. Controle que tenga tilde la columna Llave en el campo ART y la columna LÁPIZ solamente en el campo PRE.

9. Active la casilla ENVIAR ACTUALIZACIONES (SQL).

Page 26: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 25 —

10. Guarde y examine la vista. Tome nota de algunos códigos de artículo y modifique el precio. Cierre la vista. Examine la tabla ART y compruebe que los precios que modificó en el cursor de salida han cambiado también en la tabla. Si quiere comprobar el efecto de ENVIAR ACTUALIZACIONES (SQL), modifique la vista VIS4 desacti-vando esta casilla. Si examina nuevamente la vista y cambia otros precios, cuando salga de ella y examine la tabla, verá que tales cambios no la han modificado.

Ejercicio 5 Veamos cómo realizar una vista que realice lo mismo que la consulta del Ejercicio 20. Éste calcula el total vendido de cada artículo, por cada vendedor, a cada cliente. Para lograr este propósito, diseña-mos dos consultas, CON20A y CON20B, que creaban una tabla "inevitable", CON20A. Trabajando con vistas esa tabla es innecesaria. Por otro lado sería imposible de crearla, porque las vistas tienen como único destino un cursor de nombre no controlable que se ve en la ventana EXAMINAR. Cree primero la vista VIS5A. 1. Agregue las tablas VEN, ENCFAC, LINFAC y ART. Combínelas como indica este esquema:

Ven.ven = Encfac.ven Encfac.fac = Linfac.fac Linfac.fac = Art.art

2. Agregue como salida los campos VEN.NOM AS VENDEDOR, CLI.CLI, ART.NOM AS ARTÍCULO y SUM(LINFAC.CAN * LINFAC.PRE) AS IMPORTE.

3. Agrupe por VEN.VEN, ENCFAC.CLI y ART.ART. Elimine estos campos de CAMPOS SELECCIONADOS de la ficha CAMPOS.

4. Examine la vista para ver los resultados en la ventana EXAMINAR. Cree ahora cree la vista VIS5B. 1. Agregue la vista VIS5A y la tabla CLI. Combine por el campo CLI. 2. Agregue como salida los campos VIS5A.VENDEDOR,CLI.NOM AS CLIENTE, VIS5A.ARTÍCULO y

VIS5A.IMPORTE. 3. Ordene por VENDEDOR, CLIENTE y ARTÍCULO. 4. Examine la vista.

Cuando una vista 2 incluye en el panel de entorno otra vista 1, SQL debe ejecutar la vista 1 pre-viamente a ejecutar la vista 2, puesto que una de sus entradas es precisamente el cursor resultante de la vista 1. Esta inclusión de una vista dentro de otra puede repetirse varias veces. La inclusión de vistas permite ir obteniendo cursores de salida que quedan abiertos (recuerde que se eliminan si se emite un comando para cerrar las tablas abiertas, comandos que en la ejecución sucesiva no se utilizan). Si una vista 1 produce un cursor 1, éste queda abierto y puede ser tomado como entrada para una vista 2; si ésta produce como salida un cursor 2, puede tomarse como en-trada para una vista 3, y así sucesivamente. Técnicamente, una vista es un comando Select de SQL. En el caso de una vista que incluye otra vista, es en realidad un comando Select que incluye otro comando Select. El empleo inmediato de un cursor generado por una vista como entrada de otra vista evita generar tablas y preocuparse por eliminarlas.

Page 27: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 26 —

Ejercicio 6 Creemos un formulario similar a una factura impresa en papel. Queremos elegir en un COMBOBOX la factura a desplegar. Cuando se haga esto, se verá la fecha, el nombre del cliente y el total de la factura en respectivos TEXTBOXES. El detalle de cada artículo vendido, incluyendo código, nombre, cantidad, precio e importe parcial, se verán en un GRID. Las opciones del ComboBox se construirán a partir de una vista, que contendrá los campos factura, fe-cha, cliente e importe total de la factura. El aspecto del formulario será como el siguiente:

Creemos la vista VIS6 con los campos indicados. Esta vista no puede ser la hija de una relación tempo-ral , porque necesitaría un índice que no sabemos generar. Pero sí puede ser la madre de una relación temporal, porque una relación temporal necesita uno o más campos de la tabla madre y un índice en la tabla hija. Las tablas hijas van a ser CLI, para obtener el nombre del cliente, y LINFAC, para obtener las líneas componentes de la factura. Cuando elijamos una factura en el COMBOBOX, podremos "refrescar" directamente los campos fecha e importe total, porque serán parte del mismo registro del cursor produ-cido por la vista, e indirectamente el nombre del cliente y el GRID, por relaciones temporales con las ta-blas CLI y LINFAC. Notemos que, para obtener la descripción de los artículos, deberemos trazar una re-lación temporal de LINFAC a ART, relación que se materializará en cada registro del Grid y que no inter-viene en la subordinación de CLI y LINFAC a VIS6. 1. Cree la nueva vista agregando las tablas ENCFAC y LINFAC al panel de entorno, combinándolas por

el campo común FAC. 2. Seleccione los campos FAC, FEC, CLI y SUM(LINFAC.CAN * LINFAC.PRE) AS IMPTOT.

Page 28: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 27 —

3. Agrupe por ENCFAC.FAC (o por LINFAC.FAC). 4. Guarde la vista como Vis6 y ejecútela para controlar que todo va bien.

Cree ahora el formulario. 1. Agregue los objetos que muestra el gráfico anterior. 2. Defina las siguientes propiedades:

Objeto Propiedad Valor Form1 Caption Despliegue de facturas Label1 Caption Factura AutoSize .T. – Verdadero ComboBox RowSource Vis6.Fac RowSourceType 6 – Campos ColumnCount 1 ColumnWidths 75 Label2 Caption Fecha AutoSize .T. – Verdadero TextBox1 ControlSource Vis6.Fec Name Fecha Label3 Caption Cliente AutoSize .T. – Verdadero TextBox2 ControlSource Cli.Nom Name Cliente Width 200 Grid1 RecordSource Linfac ColumnCount 5 DeleteMark .F. ScrollBars 2- Vertical Name Linfac Column1 ControlSource Linfac.Art Width 30 Header1 Alignment 2 – Medio centro Caption Art Column2 ControlSource Art.Nom Width 200 Header1 Alignment 2 – Medio centro Caption Descripción Column3 ControlSource Linfac.Can Width 60 Header1 Alignment 2 – Medio centro Caption Cantidad Column4 ControlSource Linfac.Pre Header1 Alignment 2 – Medio centro Caption Precio Column5 ControlSource linfac.can*linfac.pre Alignment 2 – Medio centro Caption Importe Label4 AutoSize .T. – Verdadero Caption Total

Page 29: Pr.ctica sobre consultas y vistas - FACSO- · PDF fileEdmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008 — 3 — 5. La nueva consulta no aparece en el proyecto,

Edmundo A. Cáceres — Práctica sobre consultas y Vistas — 2008

— 28 —

TextBox3 ControlSource Vis6.Imptot InputMask 999,999.99 Name Imptot CommandButton1 Autosize .T. – Verdadero Caption Salir Name Salir

3. En el entorno de datos agregue la vista Vis6 y las tablas Cli, Linfac y Art. 4. Trace las siguientes relaciones:

Tabla madre Campo Tabla hija Índice Vis6 Fac Linfac Fac Vis6 Cli Cli Cli Linfac Art Art Art

5. En el evento CLICK del COMBOBOX, escriba: thisform.fecha.refresh thisform.cliente.refresh thisform.imptot.refresh

6. En el evento Click del CommandButton, escriba: thisform.release

7. Guarde el formulario como Vis6 y ejecútelo.