Sei sulla pagina 1di 61

MICROSOFT Visual FoxPro

(Segundo Nivel)

1
Introducción

Visual FoxPro es un sistema de administración de bases de datos relacionales.


Posee un lenguaje propio, centrado en datos y orientado a objetos muy
robusto.

Visual FoxPro ofrece a los desarrolladores un conjunto de herramientas para


crear aplicaciones de bases de datos para el escritorio, entornos
cliente/servidor, tablet PC o la Web.

Entre sus características tenemos:

 Capacidades poderosas y muy veloces para el manejo de datos nativos


y remotos.
 Flexibilidad para crear todo tipo de soluciones de bases de datos.
 Lenguaje de programación Orientado a objetos.
 Utilización de sentencias SQL en forma nativa.
 Poderoso manejo de vistas y cursores y control completo de estructuras
relacionales.
 Su propio gestor de base de datos incorporado. Sin embargo, también
puede conectarse con servidores de base de datos, tales como Oracle o
SQL Server.
 Cuenta con un motor de generación de informes renovado y muy flexible
para soluciones más robustas.

La última versión liberada es la 9.0. La próxima versión, 'Sedna', será un


poderoso y completo lenguaje que permitirá al producto interactuar aún más
con VisualStudio.net, SQLServer2005, SQLExpress2005 y Office12, Windows
Vista.

La versión 9.0 de Visual FoxPro cuenta con el SP1 en la que hay algunas
nuevas características y especialmente brinda estabilidad al producto.
Clases

En la sección dedicada a la programación orientada a objetos hemos hecho


mención a las clases, incluso hemos dado una breve definición de lo que éstas
son, y hasta nos hemos referido a clases visuales y clases no visuales. En
esta parte nos introduciremos directamente al uso de clases con Visual Fox Pro.

Una clase se puede explicar como "la definición teórica del objeto"; ya que es
una especificación genérica para objetos que comparten el mismo
comportamiento, una clase contiene las bases para la construcción del objeto
definiendo cuáles serán las propiedades, métodos y eventos que este
contendrá, cuáles serán públicos y cuáles privados.

Es importante destacar que no existe una limitación respecto de los tipos de


clases que se pueden llegar a crear y utilizar con VFP. La mayoría de las
clasificaciones que se pueden hallar mencionadas en distintos documentos que
hablan sobre el tema intentan representar una idea de lo que se puede llegar a
desarrollar, pero el hecho de que una clase imaginada con tal o cual
característica no se encuentre enmarcada dentro de las categorías "normales",
no significa para nada que no sea viable su desarrollo.

Clases visuales y clases no visuales

Como hemos visto hasta ahora las clases son una parte fundamental de la
programación orientada a objetos, todo lenguaje que se defina como "orientado
a objetos" nos ofrece una librería de clases de base sobre la cual se puede
comenzar a trabajar.

Las clases se pueden catalogar como clases visuales y clases no visuales.

Las clases visuales son las que derivan en objetos que forman parte de la
interfaz grafica con el usuario; dentro de lo que son las clases visuales que nos
ofrece VFP tenemos el formulario y casi todos sus controles (botones, líneas,
labels, etc.); cada una de estas clases tiene en sus propiedades métodos y
eventos básicos que le corresponden a su tipo, y además pueden ser
personalizadas agregándoles según nuestra necesidad nuevas propiedades y
métodos (no eventos).

Vemos a continuación la barra de herramientas de controles de formularios; allí


está la mayoría de las clases visuales que podemos instanciar ya sea para
implementarla en un formulario o para crear nuestra propia librería de clases
personalizada (hecho altamente recomendado).

67
En contrapartida con las clases visuales, tenemos las clases NO visuales;
éstas son definiciones de objetos que utilizaremos dentro del desarrollo de
nuestra aplicación con el propósito de representar en este modo cada una de
las entidades de nuestro sistema (por ejemplo: cliente, factura, proveedor, etc.),
y cada acción que esté relacionada con dichas entidades estará codificada
dentro de esta clase, del mismo modo que cada dato identificativo de ella
estará depositado en una propiedad (ver el ejemplo de cliente anteriormente
creado).

CREATE CLASSLIB (Comando)

Crea un nuevo archivo vacío de biblioteca de clases visuales (.vcx).

CREATE CLASSLIB ClassLibraryName

Parámetros
ClassLibraryName
Especifica el nombre de la biblioteca de clases visuales que se va a
crear. Si ya existe una biblioteca de clases visuales con el nombre que
especifique y SET SAFETY está establecido en ON, Visual FoxPro le
pregunta si desea sobrescribir la biblioteca de clases visuales existente.
Si SET SAFETY está establecido en OFF, el archivo existente se
sobrescribe automáticamente.

Si no especifica una extensión para el nombre de archivo, Visual FoxPro


le asigna automáticamente la extensión .vcx.

Ejemplo

El ejemplo siguiente usa CREATE CLASSLIB para crear una biblioteca de


clases visuales llamada myclslib. Una clase llamada myform basada en la clase
de base Form de Visual FoxPro se crea y almacena en la biblioteca myclslib.
Se usa SET CLASSLIB para abrir la biblioteca de clases visuales myclslib de
forma que puedan usarse las clases contenidas en ella.

CREATE CLASSLIB libcls (Crea una nueva librería de clase)

CREATE CLASS myform OF libcls AS "Form" (Crea una nueva clase dentro
de la librería de clases myclslib

SET CLASSLIB TO libcls ADDITIVE (Abre las librerias de clases).

68
ADD CLASS (Comando)

Agrega una definición de clase a una biblioteca de clases visuales .vcx.

ADD CLASS ClassName [OF ClassLibraryName1] TO ClassLibraryName2


[OVERWRITE]

Parámetros
ClassName
Especifica el nombre de la definición de clase agregada a la biblioteca
de clases visuales .vcx ClassLibraryName2.

Si omite la cláusula opcional OF ClassLibraryName1, Visual FoxPro


buscará la definición de clase en todas las bibliotecas de clases
visuales .vcx abiertas con SET CLASSLIB.

Visual FoxPro generará un error si no encuentra la definición de clase o


si ya existe una definición de clase con el nombre especificado en
ClassLibraryName2.

OF ClassLibraryName1
Especifica una biblioteca de clases visuales .vcx desde la que se copia
la definición de clase.
TO ClassLibraryName2
Especifica la biblioteca de clases visuales .vcx a la que se agrega la
definición de clase. Si especifica una biblioteca de clases visuales .vcx
que no existe, Visual FoxPro la creará y le agregará la definición de
clases.
OVERWRITE
Especifica que una definición de clase con el mismo nombre que la
definición de clase especificada con ClassName se sobrescribe. Se
generará un mensaje de error si omite OVERWRITE y ya existe una
definición de clase con el mismo nombre que ClassName en la biblioteca
de clases visuales .vcx.

Observaciones

Utilice ADD CLASS para agregar una definición de clase a una biblioteca de
clases o para copiar una definición de clase de una biblioteca de clases
visuales .vcx a otra. No es posible agregar una definición de clase desde un
programa o aplicación de Visual FoxPro (.prg o .app), ni tampoco desde un
archivo de procedimiento.

RELEASE CLASSLIB

Cierra una biblioteca de clases visuales .vcx que contiene definiciones de clase.
[, ClassLibraryName2 | ALIAS AliasName2 …]

69
RELEASE CLASSLIB ClassLibraryName1 | ALIAS AliasName1

Parámetros

ClassLibraryName1 | ALIAS AliasName1

Especifica el nombre o el alias del archivo de biblioteca de clases visuales que


se va a cerrar.

ClassLibraryName2 | ALIAS AliasName2 …

Especifica los nombres o alias de otros archivos de biblioteca de clases


visuales que se desea cerrar.

Observaciones

Las bibliotecas de clases visuales .vcx se abren con SET CLASSLIB. Una vez
abierta la biblioteca, las definiciones de clase de la biblioteca de clases visuales
están disponibles para programas y desde la ventana Comandos.

Para cerrar todas las bibliotecas de clases visuales abiertas, ejecute SET
CLASSLIB TO sin argumentos adicionales.

Ejemplo

El ejemplo siguiente usa CREATE CLASSLIB para crear una biblioteca de


clases visuales llamada myclslib. Una clase llamada myform basada en la clase
de base Form de Visual FoxPro se crea y almacena en la biblioteca myclslib.
Se usa SET CLASSLIB para abrir la biblioteca de clases visuales myclslib de
forma que puedan usarse las clases contenidas en ella. Luego se usa
RELEASE CLASSLIB para cerrar la biblioteca de clases visuales myclslib.

REMOVE CLASS (Comando)

Elimina una definición de clase de una biblioteca de clases visuales .vcx.

REMOVE CLASS ClassName OF ClassLibraryName

Parámetros
ClassName
Especifica el nombre de la definición de clase que desea quitar de la
biblioteca de clases visuales.

70
OF ClassLibraryName
Especifica el nombre de la biblioteca de clases visuales .vcx que
contiene la definición de clase que desea quitar. Si no se incluye la
extensión de archivo en ClassLibraryName, se utiliza la extensión .vcx.

Observaciones

Tenga cuidado al quitar definiciones de clase, ya que la definición de clase que


quite puede ser una clase primaria en la que se basen otras clases.

RENAME CLASS (Comando)

Cambia el nombre de una definición de clase contenida en una biblioteca de


clases visuales .VCX.

RENAME CLASS ClassName1 OF ClassLibraryName TO ClassName2

Parámetros
ClassName1
Especifica el nombre de la definición de clase a la que se va a cambiar
el nombre.
OF ClassLibraryName
Especifica el nombre de la biblioteca de clases visuales .vcx que
contiene la definición de clase cuyo nombre desea cambiar. Si no
especifica una extensión de arc hivo en ClassLibraryName, Visual
FoxPro asignará automáticamente la extensión .vcx.
TO ClassName2
Especifica el nuevo nombre de la definición de clase.

Observaciones

Visual FoxPro no actualiza otras definiciones de clase de la biblioteca de clases


visuales que hacen referencia a la definición de clase cuyo nombre ha
cambiado, por lo que deberá tener cuidado al cambiar de nombre las
definiciones de clase.

Ejemplo

El ejemplo siguiente usa CREATE CLASSLIB para crear una biblioteca de


clases visuales llamada myclslib. Se crea una clase llamada myform (basada
en la clase de base Form de Visual FoxPro) con CREATE CLASS y se
almacena en la biblioteca de clases visuales myclslib. Luego se usa RENAME
CLASS para cambiar el nombre de la clase de myform a yourform.

RENAME CLASS myform OF myclslib TO yourform (Cambia el nombre de la


clase)

71
Aplicaciones Cliente Servidor

Puede usar a Visual FoxPro en desarrollos frontales para aplicaciones robustas


cliente/servidor. El visual FoxPro combina el soporte al más alto nivel de vistas
actualizables de datos del servidor con acceso directo a la sintaxis nativa del
servidor usando SQL transferible. Esto le da una fundación sólida para
desarrollar soluciones cliente/servidor versátiles. Un diccionario de datos de
amplio espectro, vistas locales y remotas, soporte nulo, transacciones, y un
acceso para fuentes de datos ODBC; todas estas características contribuyen a
lo que necesita para el desarrollo cliente/servidor. El paso más importante a la
hora de generar con éxito una aplicación cliente-servidor es crear un buen
diseño. Cuando diseñe una aplicación cliente/servidor, debe balancear muchos
requisitos de configuración. Buscará desarrollar aplicaciones más rápidas y
más productivas para sus usuarios. También deseará asegurar la integridad de
los datos en la aplicación, con la mayor integración de hardware existente y
desarrollar en escalabilidad para el futuro. Además, como un desarrollador de
Visual FoxPro, buscará hacer el proceso de desarrollo tan fluido y eficiente en
costos como sea posible.

Desarrollo Cliente / Servidor en VFP

Introducción al Desarrollo con Cliente/Servidor con Visual Fox Pro

Las capacidades para el desarrollo de aplicaciones en el entorno


cliente/servidor que posee Visual FoxPro sumado esto a la potencia
versatilidad a la hora del manejo de datos, posicionan a esta herramienta aún
más en un lugar de privilegio al momento de decidir cuál va a ser la
herramienta que utilizare en el comienzo del desarrollo de una nueva aplicación.

Quienes han venido desarrollando aplicaciones a través de los años con


FoxPro o cualquier otra herramienta xBase, cuando desarrollan aplicaciones
multiusuarios, han utilizado la metodología de alojar las tablas en servidores;
ésta era la forma de centralizar nuestros datos, pero ésto no era más que una
forma de trabajar en un modo denominado "file server", ya que aunque los
datos estuvieran alojados en una máquina remota o centralizada, el
procesamiento completo de todas las operaciones de lectura y escritura de
datos se realizaba en el procesador del cliente.

Con la popularización de los "servidores de datos" como por ejemplo SQL


Server, nos vemos en la posición de que nuestras empresas puedan, ante la
necesidad, adquirir un motor de datos como el mencionado anteriormente o
cualquier otro y que nuestras aplicaciones deban comenzar a trabajar con
estas bases de datos dejando ya nuestro motor nativo.

72
Visual Fox Pro nos ofrece acceso a los más diversos orígenes de datos, ODBC,
ADO, XML etc., para poder acceder a los mencionados repositorios de datos,
debemos según la tecnología de que se trate realizar la correspondiente
conexión.

Si estamos hablando de conectarnos a una base de datos SQL Server, o


cualquier otro que soporte ODBC, debemos tener un ODBC Data Source
creado y desde allí hacer uso del mismo, por ejemplo, supongamos que
tenemos un ODBC Data Source llamado "Prueba":

El cual nos ofrece acceso a una base de datos SQL, a través del mismo,
nosotros tenemos la posibilidad de abrir una conexión con dic ho origen de
datos y ejecutar sentencias sobre este que devuelvan algún resultado, veamos
un rápido ejemplo de la forma de efectuar esto:

nConnHandle = SQLCONNECT("Prueba")
SQLEXEC(nConnHandle, "Select * from Customers", "Clientes")

73
Luego de ejecutar esto, tranquilamente podemos pedir un browse de los datos
recuperados, pruébalo, éste se verá así:

Según lo que podemos observar en estas dos líneas de código, lo que


hacemos es lo siguiente: en la primera, inicializamos una variable llamada
nConnHandle sobre la cual almacenamos el número de conexión que después
le pasamos a la instrucción que ejecutará la sentencia deseada; en la segunda
línea, a la sentencia SQLEXEC le pasamos tres parámetros: el primero será el
número de conexión generada en la línea anterior; el segundo, el comando que
queremos ejecutar sobre el motor de datos y como tercer parámetro (este es
opcional) le decimos cómo se llamará el cursor que se generará de nuestro
lado en caso de que el comando ejecutado devuelva un conjunto de registros,
como en este caso.

Una vez ejecutado esto podemos trabajar sobre el cursor generado de la


misma forma que acostumbramos a hacerlo normalmente, asignando este
resultado a una grilla para mostrarlo o hacer vinculación de dichos datos sobre
un grupo de textboxes para navegarlos mediante una botonera; todas estas
modalidades de tratamiento de datos iremos viéndolas con el correr de estos
documentos, por lo pronto hemos visto con que facilidad podemos acceder a
un motor de datos remoto.

Hemos accedido a través de una fuente de datos ODBC a un motor de datos


SQL Server, teniendo los correspondientes drivers de ODBC podemos acceder
a cualquier motor de datos, pero como lo hemos dicho en un principio, no
estamos limitados solamente a ODBC; Visual Fox Pro, desde la versión 7 tiene
la capacidad también de acceder a través de OLEDB a todos los orígenes de
datos que soporten esta arquitectura, y tampoco nos quedamos fuera de lo que
es el mundo XML, con la clase XMLAdapter tenemos plena integración con

74
esta especificación de manejo de documentos y podemos recibir, procesar y
enviar documentos multi tabla en forma jerárquica y, lo más importante
establecer una comunicación de igual a igual con la arquitectura .NET a través
de esta metodología de transporte de datos.

Conexiones

Para acceder a datos remotos necesita crear una conexión a un origen de


datos remotos válido, el cual generalmente es un servidor para el cual se ha
instalado un controlador Open Database Connectivity (ODBC) y se establece
un nombre de origen de datos ODBC. Desde dentro de Visual FoxPro, puede
definir un origen de datos y sus conexiones. Para más información.

Para recuperar datos desde un origen de datos remoto, use vistas remotas,
estas usan sintaxis SQL remota para seleccionar información de tablas
almacenadas en un origen de datos ODBC.

Definir una conexión

En Visual FoxPro, puede crear y almacenar en una bases de datos una


definición de conexión con nombre, a la que se puede referir desde ese
momento por su nombre cuando cree una vista remota. También puede
establecer propiedades de la conexión con nombre para optimizar la
comunicación entre Visual FoxPro y el origen de datos remoto. Cuando active
una vista remota, la conexión de la vista se convertirá en la canalización al
origen de datos remoto.

Nota Para crear una conexión es imprescindible tener abierta una base de
datos.

Para crear una nueva conexión

1. En el Administrador de proyectos, seleccione una base de datos.


2. Seleccione Conexiones y elija Nuevo.
3. En el Diseñador de conexiones, introduzca las opciones
correspondientes a los requisitos de su servidor.
4. En el menú Archivo, elija Guardar.
5. En el cuadro de diálogo Guardar, escriba un nombre para la conexión
en el cuadro Nombre de conexión.
6. Elija Aceptar. También puede crear una conexión si elige Nuevo en el
menú Archivo y selecciona la opción Conexión.

–O bien–

 Abra una base de datos y utilice el comando CREATE CONNECTION


para abrir el Diseñador de conexiones.

75
–O bien–

 Utilice el comando CREATE CONNECTION con un nombre de conexión.

Por ejemplo, para crear una conexión en la base de datos testdata que
almacene la información necesaria para conectarse al origen de datos ODBC
sqlremote, puede escribir el código siguiente:

OPEN DATABASE testdata


CREATE CONNECTION remote_01 DATASOURCE sqlremote userid
password

Visual FoxPro muestra remote_01 como el nombre de la conexión en el


Administrador de proyectos.

La creación de una conexión con nombre en su base de datos no utiliza ningún


recurso remoto ni de red, ya que Visual FoxPro no activa la conexión hasta que

76
usted utiliza la vista. Hasta que active la conexión, la conexión con nombre sólo
existe como una definición de conexión almacenada como una fila en el
archivo .dbc de la base de datos. Cuando utilice una vista remota, Visual
FoxPro usará la conexión con nombre mencionada en la vista para crear una
conexión activa con el origen de datos remoto y enviará la solicitud de datos al
origen remoto utilizando la conexión activa como canalización.

Puede crear opcionalmente una vista que especifique únicamente el nombre


del origen de datos, en lugar del nombre de la conexión. Cuando utilice la vista,
Visual FoxPro usará la información de ODBC acerca del origen de datos para
crear y activar una conexión con el origen de datos. Cuando cierre la vista se
cerrará la conexión.

Prioridad de nombres para conexiones y orígenes de datos

Cuando utilice el comando CREATE SQL VIEW con la cláusula CONNECTION,


especifique un nombre que represente una conexión o bien un origen de datos.
Visual FoxPro buscará primero en la base de datos actual una conexión con el
nombre que especificó. Si no existe ninguna conexión con ese nombre en la
base de datos, Visual FoxPro buscará entonces un origen de datos ODBC
establecido con el nombre especificado. Si su base de datos actual contiene
una conexión con nombre cuyo nombre coincide con el de un origen de datos
ODBC de su sistema, Visual FoxPro la encontrará y utilizará la conexión con
nombre.

Mostrar instrucciones de inicio de sesión ODBC

Cuando use una vista cuya información de inicio de sesión de conexión no esté
totalmente especificada, Visual FoxPro puede mostrar un cuadro de diálogo
específico del origen de datos que le pida la información que falte.

Puede controlar si Visual FoxPro le pedirá la información que dejó sin


especificar en el momento de la conexión.

Para controlar la presentación de instrucciones de inicio de sesión ODBC

1. En el Administrador de proyectos, seleccione el nombre de la conexión y


elija Modificar para abrir el Diseñador de conexiones.
2. En el área Mostrar instrucciones de inicio de sesión ODBC, elija una
opción.

–O bien–

 Utilice la propiedad DispLogin de las funciones DBSETPROP( ) o


SQLSETPROP( ).

77
Usar una conexión existente

Puede utilizar una conexión con nombre ya existente para crear una vista
remota. Puede ver una lista de las conexiones disponibles en la base de datos
y utilizar el Administrador de proyectos o el comando DISPLA Y
CONNECTIONS.

Para determinar las conexiones existentes

 En el Administrador de proyectos, seleccione una base de datos y


seleccione Conexiones.

–O bien–

 Utilice el comando DISPLAY CONNECTIONS.

Por ejemplo, el código siguiente muestra las conexiones de la base de datos


testdata:

OPEN DATABASE testdata - luego - DISPLAY CONNECTIONS

Configurar un origen de datos ODBC

Antes de que pueda crear vistas remotas o usar un paso a través de SQL, tiene
que instalar un controlador ODBC y configurar el origen de datos ODBC.

Elegir un controlador ODBC

Para instalar los controladores ODBC para estos tipos de datos, use el
programa de instalación de Visual FoxPro. Si elige la opción de instalación
Completa, se instalan todos los controladores.

Cuando haya elegido un controlador, puede usar el origen de datos


predeterminado o agregar un origen de datos ODBC.

Para agregar un origen de datos ODBC

1. Elija el icono Herramientas administrativas en el Panel de control de


Windows.
2. Elija el acceso directo Orígenes de datos ODBC.
3. En el cuadro de diálogo Administrador de orígenes de datos ODBC,
haga clic en Agregar y, a continuación, seleccione el controlador que
desee en la lista Controladores ODBC instalados y elija Aceptar.
4. En el cuadro de diálogo Configuración de ODBC, establezca los
valores de las opciones conforme sea necesario y elija Aceptar.

78
Para obtener información acerca de cómo configurar un origen de datos
específico del controlador elegido, elija el botón Ayuda en el cuadro de diálogo
Configuración de ODBC.

Instalar orígenes de datos ODBC

Puede obtener soporte para Conectividad abierta de bases de datos (ODBC) si


elige la opción de instalación Completa o Personalizada. Con ODBC, puede
tener acceso a un origen de datos SQL Server desde Visual FoxPro; sin
embargo, antes de tener acceso al origen de datos, deberá definirlo.

Conexión de Visual FoxPro con los orígenes de datos ODBC

Para definir un origen de datos

1. Cambie al Panel de control de Windows y elija el icono ODBC.


2. En el cuadro de diálogo Orígenes de datos, elija Agregar.
3. En el cuadro de diálogo Agregar origen de datos, seleccione el
controlador ODBC SQL Server y elija Aceptar.
4. En el cuadro de diálogo Instalación de ODBC SQL Server, escriba el
nombre, la descripción y cualquier otra información del origen de datos y,
a continuación, elija Aceptar.
5. En el cuadro de diálogo Orígenes de datos, elija Cerrar.

79
Utilizar la tecnología de paso a través de SQL

Su aplicación cliente-servidor puede tener acceso a datos del servidor


mediante:

 Vistas remotas
 Paso a través de SQL

Las vistas remotas proporcionan el método más común y más fácil para tener
acceso a datos remotos y actualizarlos. Los asistentes para conversión pueden
crear automáticamente vistas remotas en la base de datos como parte del
conversión, o puede usar Visual FoxPro para crear vistas remotas después de
hacer la conversión. Para obtener más información acerca de las vistas
remotas.

La tecnología de paso a través de SQL le permite enviar instrucciones SQL


directamente a un servidor. Las instrucciones de paso a través de SQL, como
se ejecutan en el servidor backend, son formas eficaces de mejorar el
rendimiento de las aplicaciones cliente-servidor. La tabla siguiente compara las
vistas remotas con el paso a través de SQL:

Comparación de las tecnologías de vista remota y paso a través de SQL

Vista remota Paso a través de SQL


Se basa en una instrucción SQL Se basa en cualquier instrucción nativa
SELECT. de SQL Server, que permiten
instrucciones de definición de datos o la
ejecución de procedimientos
almacenados del servidor.
Se puede usar como origen de datos No se puede usar como origen de datos
para controles en tiempo de diseño. para controles.
No ofrece la posibilidad de ejecutar Proporciona un método para usar
comandos DDL sobre el origen de comandos DDL sobre el origen de datos.
datos.
Busca un conjunto de resultados. Busca uno o varios conjuntos de
resultados.
Proporciona administración deRequiere administración de conexiones
conexiones incorporadas. explícita.
Proporciona información deNo proporciona información de
actualización predeterminadaactualización predeterminada.
incorporada para actualizar, insertar y
eliminar.
Proporciona ejecución SQL implícita y Proporciona ejecución SQL explícita y
búsqueda de datos. control de búsqueda de resultados.
No proporciona control deProporciona control de transacciones
transacciones. explícito.
Almacena propiedades de formaProporciona propiedades temporales

80
persistente en bases de datos. para cursor de paso a través de SQL,
sobre la base de propiedades de
sesiones.
Utiliza búsqueda progresivaEs compatible con búsqueda asíncrona a
asíncrona al ejecutar SQL. través de programa.

La tecnología de paso a través de SQL ofrece las siguientes ventajas frente a


las vistas remotas:

 Puede usar funcionalidad específica de servidor, como procedimientos


almacenados y funciones intrínsecas basadas en servidor.
 Puede usar extensiones a SQL admitidas por el servidor, así como
definición de datos, administración de servidor y comandos de seguridad.
 Tiene más control sobre instrucciones Update, Delete e Insert de paso a
través de SQL.
 Tiene más control sobre transacciones remotas.

Sugerencia Visual FoxPro puede controlar consultas de paso a través


de SQL que devuelven más de un conjunto de resultados.

Las consultas de paso a través de SQL también tienen desventajas:

 De forma predeterminada, una consulta de paso a través de SQL


siempre devuelve una instantánea no actualizable de datos remotos, que
se almacena en un cursor de vista activo. Puede convertir el cursor en
actualizable al definir propiedades con la función CURSORSETPROP( ).
En cambio, una vista remota actualizable normalmente no requiere que
establezca propiedades para poder actualizar datos remotos, porque los
valores de las propiedades se almacenan en la base de datos con la
definición de la vista.
 Tiene que escribir comandos SQL directamente en la ventana
Comandos o en un programa, en lugar de usar el Diseñador de vistas
gráfico.
 Es usted quién crea y administra la conexión al origen de datos.

Si usa vistas remotas o paso a través de SQL, puede consultar y actualizar


datos remotos. En muchas aplicaciones utilizará tanto vistas remotas como
paso a través de SQL.

Usar funciones de paso a través de SQL

Para usar el paso a través de SQL para conectarse a un origen de datos ODBC
remoto, debe llamar en primer lugar a la función SQLCONNECT( ) de Visual
FoxPro para crear una conexión. Una vez hecho esto, use las funciones de
paso a través de SQL para enviar comandos al origen de datos remoto para su
ejecución.

81
Para usar funciones de paso a través de SQL de Visual FoxPro

1. Confirme que el sistema puede conectar su equipo al origen de datos.


Use una utilidad como ODBC Test para ODBC.
2. Establezca una conexión al origen de datos mediante las funciones
SQLCONNECT( ) o SQLSTRINGCONNECT( ).

Por ejemplo, si está conectando Visual FoxPro al origen de datos de


SQL Server sqlremote, puede iniciar una sesión con el siguiente
comando:

nConnectionHandle =
SQLCONNECT('sqlremote','<userid>','<password>')

Nota También puede usar la función SQLCONNECT( ) para conectarse


a una conexión con nombre.

3. Use funciones de paso a través de SQL de Visual FoxPro para obtener


datos en cursores de Visual FoxPro y procesar la obtención de datos
con comandos y funciones estándar de Visual FoxPro.

Por ejemplo, puede consultar a la tabla authors y examinar el cursor


resultante usando este comando:

? SQLEXEC(nConnectionHandle,"select * from
authors","mycursorname")
BROWSE

4. Desconéctese del origen de datos con la función SQLDISCONNECT( ).

Funciones de paso a través de SQL de Visual FoxPro

La siguiente tabla muestra las funciones SQL de Visual FoxPro que admiten el
trabajo con orígenes de datos remotos, agrupados según la tarea.

Tarea Función Objetivo


Administración deSQLCONNECT( ) Conectarse a un origen de
conexiones datos para operaciones de
paso a través de SQL.
SQLSTRINGCONNECT( ) Conectarse a un origen de
datos con sintaxis de cadena
de conexión ODBC.
SQLDISCONNECT( ) Interrumpir una conexión a un
origen de datos ODBC,
haciendo obsoleto el
controlador de conexión
especificado.

82
Control y ejecución SQLCANCEL( ) Cancelar una consulta SQL
de instrucciones que se ejecuta de forma
SQL asíncrona en una conexión
activa.
SQLEXEC( ) Ejecutar una consulta de
paso a través de SQL en una
conexión activa; devuelve el
número de conjuntos de
resultados generados o 0 si
SQLEXEC( ) se sigue
ejecutando (procesamiento
asíncrono).
SQLMORERESULTS( ) Colocar otro conjunto de
resultados en un cursor.
Devuelve 0 si la instrucción
que crea el conjunto de
resultados se sigue
ejecutando.
SQLPREPARE( ) Precompilar la instrucción
SQL en el origen de datos y
vincular los parámetros de
Visual FoxPro, es decir,
guardar las expresiones de
parámetros reales para todos
los parámetros de la
instrucción SQL.
SQLCOMMIT( ) Solicitar una confirmación de
transacción.
SQLROLLBACK( ) Solicitar que se deshaga una
transacción.
Información deSQLCOLUMNS( ) Almacenar una lista de
origen de datos nombres de columnas e
información acerca de cada
una en un cursor. Devuelve 1
si la función tiene éxito o 0 si
la función se sigue
ejecutando.
SQLTABLES( ) Almacenar los nombres de
tablas del origen en un
cursor. Devuelve 1 si la
función tiene éxito o 0 si la
función se sigue ejecutando.
Control variado SQLGETPROP( ) Obtener una propiedad de
conexión de una conexión
activa.
SQLSETPROP( ) Establecer una propiedad de
una conexión activa.

83
Las instrucciones SQLEXEC( ), SQLMORERESULTS( ), SQLTABLES( ) y
SQLCOLUMNS( ) se pueden cancelar en modo síncrono al presionar ESC si
SET ESCAPE está activado. Puede cancelar estas instrucciones en cualquier
momento en modo asíncrono si ejecuta SQLCANCEL( ). Todas las demás
instrucciones de paso a través de SQL funcionan de forma síncrona y no se
pueden interrumpir.

Crear conjuntos de resultados

Cuando usa las funciones de paso a través de SQL SQLEXEC( ) o


SQLMORERESULTS( ) para consultar datos, Visual FoxPro le devuelve los
datos en uno o muchos conjuntos de resultados. Los conjuntos de resultados
se originan a partir de cursores del origen de datos del servidor y se convierten
en cursores de Visual FoxPro. El nombre predeterminado para un conjunto de
resultados es SQLRESULT.

Crear una vista remota

Cuando tiene un origen de datos o una conexión con nombre válidos, puede
crear una vista remota con el Administrador de proyectos o el lenguaje de
programación. Una vista remota es similar a una vista local, pero usted agrega
un nombre de conexión o de origen de datos al definir la vista. La instrucción
SQL de la vista remota utiliza la sintaxis nativa del servidor.

Para crear una vista remota

1. En el Administrador de proyectos, seleccione una base de datos,


seleccione Vistas remotas y elija Nuevo para abrir el Diseñador de
vistas.
2. Elija Nueva vista.
3. En el cuadro de diálogo Seleccionar conexión u origen de datos,
seleccione la opción Orígenes de datos disponibles.

–O bien–

 Utilice el comando CREATE SQL VIEW con la cláusula REMOTE o la


cláusula CONNECTION.

84
Si usa la cláusula CONNECTION con el comando CREATE SQL VIEW, no
necesitará incluir la palabra clave REMOTE. Visual FoxPro identifica la vista
como remota por la presencia de la palabra clave CONNECTION. Por ejemplo,
si tiene la tabla products de la base de datos Testdata en un servidor remoto, el
código siguiente creará una vista remota de la tabla products:

85
OPEN DATABASE testdata
CREATE SQL VIEW product_remote_view ;
CONNECTION remote_01 ;
AS SELECT * FROM products

Puede utilizar el nombre de un origen de datos en lugar del nombre de una


conexión cuando cree una vista remota. También puede elegir entre omitir el
nombre de la conexión o del origen de datos remoto cuando utilice el comando
CREATE SQL VIEW con la cláusula REMOTE. Visual FoxPro mostrará
entonces el cuadro de diálogo Seleccionar conexión u origen de datos, en el
que podrá elegir un origen de datos o una conexión válidos.

Crear una nueva vista remota

Para tener acceso a los datos remotos de una vista, puede usar una conexión
existente o crear una conexión para usar la nueva vista.

Para crear una nueva vista remota

1. Seleccione un origen de datos o una conexión y elija Aceptar.


2. En el cuadro de diálogo de inicio de sesión de Microsoft SQL Server o
en otro cuadro de diálogo de inicio de sesión, escriba su Id. de inicio de
sesión y su contraseña, si es necesario.

–O bien–

Si previamente ha definido y guardado una conexión, seleccione la


opción Conexiones.

También puede elegir Nuevo en el menú Archivo y seleccionar la opción Vista


remota.

Una vez establecida la conexión aparecerá el cuadro de diálogo Abrir, que le


permite seleccionar una tabla del servidor remoto.

Cuando haya seleccionado una tabla, aparecerá el Diseñador de vistas.

Para continuar con la creación de la vista remota, puede seleccionar campos


de resultados y establecer filtros, igual que para una vista local.

Usar un Asistente para vistas

También puede crear una vista remota con un Asistente para vistas. Para
configurar una vista actualizable mediante tablas de un origen de datos ODBC,
utilice el Asistente para vistas remotas.

86
Para crear una vista remota con un asistente

1. En el Administrador de proyectos, seleccione una base de datos.


2. Seleccione Vistas remotas y elija Nuevo.
3. Elija el botón Asistente para vistas.
4. Siga las instrucciones de las pantallas del asistente.

Después de crear una vista, puede abrir el Diseñador de bases de datos y


comprobar que la vista se muestra de la misma manera que una tabla en el
esquema, con el nombre e icono de la vista en lugar del nombre e icono de la
tabla.

Si combina dos o más tablas en el Diseñador de vistas remotas, el Diseñador


usa combinaciones internas (o equicombinaciones) y coloca la condición de
combinación en la cláusula WHERE. Si desea usar una combinación externa,
el Diseñador de vistas remotas sólo proporciona combinaciones externas
izquierdas, la sintaxis con la que es compatible ODBC. Si necesita
combinaciones externas derechas o completas o sólo quiere usar una sintaxis
nativa para una combinación externa izquierda, cree la vista mediante
programación.

Trabajar con datos remotos mediante la tecnología de paso a través de


SQL

Cuando recupere un conjunto de resultados mediante paso a través de SQL,


puede ver y controlar las propiedades de su cursor de conjunto de resultados
mediante las funciones CURSORGETPROP( ) y CURSORSETPROP( ) de
Visual FoxPro. Estas funciones son las mismas que las que se emplean para
establecer las propiedades en un cursor de vista activo.

Nota Los cursores no son objetos y no están vinculados al modelo de objetos.


No obstante, puede ver sus propiedades o atributos, con CURSORGETPROP( )
y establecer sus propiedades con CURSORSETPROP( ).

Establecer las propiedades del cursor para datos remotos

La siguiente tabla indica las propiedades de cursor de Visual FoxPro que


permiten trabajar con vistas y conjuntos de resultados conectados, agrupadas
por categorías de tareas.

87
Propiedades de cursor de Visual FoxPro

Tarea Propiedad Objetivo


Ver la definición delSQL Contiene la instrucción SQL a
cursor partir de la cual se creó el
cursor.
Controlar lasConnectHandle Controlador para la conexión
interacciones entre remota empleada por el cursor.
Visual FoxPro y
ODBC
ConnectName Nombre de la conexión
empleada por el cursor.
Prepare Especifica si la consulta para la
vista se prepara antes de
ejecutarse.
FetchAsNeeded Especifica si las filas se buscan
automáticamente durante el
bucle inactivo o sólo cuando es
necesario.
CompareMemo Especifica si los campos Memo
y General participan en la
cláusula WHERE de una
instrucción UPDATE,
independientemente del valor
de la propiedad UpdateType
FetchMemo Especifica si los campos Memo
y General se buscan
automáticamente con los
conjuntos de resultados o si se
buscan después, previa
petición, cuando se abra el
campo Memo o General.
UseMemoSize Especifica el tamaño mínimo de
columna (1 a 255) de los
conjuntos de resultados para los
que se devuelven columnas en
campos Memo.
FetchSize Especifica el número de filas
que se buscan simultáneamente
desde el conjunto de resultados
remoto.
MaxRecords Especifica el número máximo de
filas buscadas cuando se
devuelven los conjuntos de
resultados.
Actualizar datos SendUpdates* Especifica si las actualizaciones

88
del cursor se envían a las tablas
en las que se basa el cursor.
BatchUpdateCount Especifica el número de
instrucciones de actualización
enviadas al servidor backend
para tablas almacenadas en
búfer.
Tables* Lista delimitada por comas de
nombres de tablas del origen de
datos; se usa para definir el
alcance de las propiedades
UpdateNameList y
UpdatableFieldsList.
KeyFieldList* Lista delimitada por comas de
campos de Visual FoxPro que
representan la clave principal
del conjunto de resultados
utilizado para las
actualizaciones.
UpdateNameList* Lista delimitada por comas que
combina los campos de Visual
FoxPro del cursor con los
nombres de tabla y columna de
los campos a los que desea
enviar las actualizaciones.
UpdatableFieldList* Lista delimitada por comas de
los campos de Visual FoxPro
para los que se envían
actualizaciones.
Almacenamiento enEspecifica el tipo de
búfer almacenamiento en búfer que
se ejecuta en el cursor.
UpdateType Especifica si se debe realizar
una actualización utilizando
cláusulas UPDATE o DELETE,
y luego INSERT.
WhereType Especifica qué se debe incluir
en la cláusula WHERE para las
actualizaciones de los datos de
la tabla.

* Propiedades que es necesario establecer para poder actualizar datos.

Estas propiedades se utilizan para controlar la forma en que la aplicación


interactúa con datos remotos, como el establecimiento del número de filas
recuperadas durante la búsqueda progresiva y el control de almacenamiento en
búfer y de actualizaciones de datos remotos.

89
Usar la ficha Datos remotos del cuadro de diálogo Opciones

Algunas propiedades de cursor heredan sus valores iniciales del entorno,


mientras que otras solamente están disponibles a nivel del cursor. Algunas
propiedades están disponibles para cursores que representan vistas remotas y
tablas conectadas de paso a través de SQL u ODBC.

Puede controlar algunas configuraciones de propiedades de conexión y de


cursor a través de la ficha Datos remotos del cuadro de diálogo Opciones. Al
presentar la ficha Datos remotos, los valores del cuadro de diálogo representan
los valores del cursor para la sesión actual y los valores predeterminados
globales de Visual FoxPro para la conexión. Cuando modifique los valores de la
ficha Datos remotos y elija Aceptar, los nuevos valores se guardarán en la
sesión actual del cursor y en los valores predeterminados globales de la
conexión. Si elige Establecer como predeterminado, los valores se incluirán en
los valores del sistema configurables en su equipo. El siguiente diagrama
ilustra estas interacciones.

Establecer propiedades con paso a través de SQL

Cuando cree un cursor, éste heredará los valores de sus propiedades, tales
como UpdateType y UseMemoSize, del cursor del entorno o del cursor 0 de la
sesión actual. Puede cambiar estos valores predeterminados de las
propiedades mediante la función CURSORSETPROP( ) con 0 como número de
cursor.

90
Tras crear un cursor de vista con paso a través de SQL, puede modificar los
valores de las propiedades del cursor activo mediante la función
CURSORSETPROP( ) para el cursor de vista. Los cambios que realice con
CURSORSETPROP( ) serán temporales: los valores temporales de la vista
activa desaparecen cuando se cierra dicha vista y los valores temporales del
cursor 0 se eliminan cuando se cierra la sesión de Visual FoxPro.

Las conexiones heredan las propiedades de forma similar. Las propiedades


predeterminadas para la conexión 0 se heredan al crear y almacenar una
conexión con nombre en una base de datos. Puede modificar estos valores
predeterminados de las propiedades para la conexión 0 con la función
SQLSETPROP( ). Una vez creada la conexión y almacenada en una base de
datos, puede modificar las propiedades de la conexión con la función
DBSETPROP( ). Cuando utilice una conexión, la conexión activa heredará los
valores de las propiedades almacenados en la base de datos. Puede modificar
estas propiedades en la conexión activa mediante la función SQLSETPROP( )
para el controlador de conexión.

Tanto los cursores de vista de paso a través de SQL como las conexiones con
nombre pueden utilizar un origen de datos ODBC con nombre. Si utiliza un
origen de datos ODBC en un cursor de vista de paso a través de SQL, la
conexión heredará sus propiedades de los valores predeterminados de la
sesión.

El siguiente diagrama ilustra las propiedades heredadas de los cursores y las


conexiones creados con paso a través de SQL. Las líneas grises representan
el flujo de herencia de las propiedades y las líneas negras representan los
comandos de Visual FoxPro.

91
Herencia de las propiedades de cursor y conexión de paso a través de
SQL (SPT)

92
Actualizar datos

Para actualizar datos, puede usar almacenamiento en búfer, transacciones o


vistas.

Realizar actualizaciones con almacenamiento en búfer

Después de elegir el método de almacenamiento en búfer y el tipo de bloqueo,


active el almacenamiento en búfer de registros o tablas.

Para activar el almacenamiento en búfer

Elija una de las opciones siguientes:

 En el Diseñador de formularios, establezca la propiedad


BufferModeOverride del cursor en el entorno de datos del formulario.

–O bien–

 En el código, establezca la propiedad Buffering.

Por ejemplo, puede activar el almacenamiento pesimista de filas en


búfer si coloca el código siguiente en el procedimiento Init de un
formulario:

CURSORSETPROP('Buffering', 2)

Después escriba código para las operaciones de actualización en el código del


método apropiado para los controles.

Para escribir las modificaciones en la tabla original, utilice TABLEUPDATE( ).


Para cancelar las modificaciones después de una operación errónea de
actualización en una tabla restringida por reglas, utilice TABLEREVERT( ).
TABLEREVERT( ) es válido aunque el almacenamiento explícito de tablas en
búfer no esté activado. Para especificar un nivel de verificación de la integridad
de tabla, más bajo que el de al configuración predeterminada, utilice el
comando SET TABLEVALIDATE.

93
El ejemplo siguiente muestra cómo actualizar registros cuando está activado el
almacenamiento pesimista de registros en búfer.

Ejemplo de actualización mediante búferes de registros y tablas

Código Comentarios
OPEN DATABASE testdata En el código Init del
USE customers formulario, abre la tabla y
CURSORSETPROP('Buffering', 2) activa el almacenamiento
pesimista de registros en
búfer.
lModified = .F.
FOR nFieldNum = 1 TO FCOUNT() Se desplaza por campos y
IF GETFLDSTATE(nFieldNum) = 2 comprueba los que se han
lModified = .T. modificado.
EXIT
ENDIF Nota Este código podría
ENDFOR estar en el evento Click de
un botón de comando
"Guardar" o "Actualizar".
IF lModified Busca el siguiente registro
nResult = MESSAGEBOX; modificado.
("El registro fue modigiaco. Guardarlo?", ;
4+32+256, "Datos cambiaron")
IF nResult = 7 Muestra el valor actual y da
TABLEREVERT (.F.) al usuario la posibilidad de
ENDIF invertir el cambio del
ENDIF campo actual.
SKIP
IF EOF()
MESSAGEBOX( "already at bottom")
SKIP -1 SKIP garantiza que se
ENDIF escribe el último cambio.
THISFORM.Refresh

Administrar actualizaciones mediante transacciones

Incluso si utiliza el almacenamiento en búfer pueden surgir problemas. Si desea


proteger las operaciones de actualización y recuperar una sección completa de
código como una unidad, utilice transacciones.

La incorporación de transacciones a su aplicación proporciona una protección


adicional al almacenamiento en búfer de registros y tablas de Visual FoxPro,
situando una sección completa de código en una unidad protegida y
recuperable. Puede anidar transacciones y emplearlas para proteger
actualizaciones almacenadas en búfer. Las transacciones de Visual FoxPro
sólo están disponibles con tablas y vistas pertenecientes a una base de datos.

94
Ajustar segmentos de código

Una transacción actúa como un empaquetador que almacena en memoria


caché o en disco las operaciones de actualización de datos, en lugar de aplicar
directamente esas actualizaciones a la base de datos. La actualización real de
la base de datos se realiza al final de la transacción. Si por alguna razón el
sistema no puede realizar las operaciones de actualización en la base de datos,
podrá deshacer la transacción completa para que no se lleve a cabo ninguna
actualización.

Nota Las operaciones de actualización almacenadas en búfer que se hayan


realizado fuera de una transacción se ignoran en otra transacción de la misma
sesión de datos.

Comandos que controlan transacciones

Visual FoxPro proporciona tres comandos y una función para administrar una
transacción:

Para Utilice
Iniciar una transacción BEGIN TRANSACTION
Determinar el nivel actual de la transacción TXNLEVEL( )
Invertir todos los cambios realizados desde laROLLBACK
instrucción BEGIN TRANSACTION más reciente
Bloquear registros, grabar en disco todos losEND TRANSACTION
cambios realizados en tablas de la base de datos
desde la instrucción BEGIN TRANSACTION más
reciente y, a continuación, desbloquear los
registros

Puede utilizar transacciones para ajustar modificaciones de tablas,


archivos .cdx estructurales y archivos memo asociados a tablas de una base de
datos. Las operaciones en las que intervienen variables y otros objetos no
respetan las transacciones, por lo que no se pueden deshacer o confirmar.

Nota Cuando se utilicen los datos almacenados en tablas remotas, el control


de los comandos de la transacción sólo actualiza los datos de la copia local del
cursor de la vista; las actualizaciones de tablas base remotas no se ven
afectadas. Para habilitar las transacciones manuales en tablas remotas, utilice
SQLSETPROP( ) y, a continuación, controle al transacción mediante
SQLCOMMIT( ) y SQLROLLBACK( ).

En general, deberá utilizar las transacciones con búferes de registro en lugar


de almacenamiento de tablas en búfer, salvo para ajustar llamadas de
TABLEUPDATE( ). Si incluye un comando TABLEUPDATE( ) en una

95
transacción, podrá deshacer una actualización errónea, resolver la causa del
error y, a continuación, volver a intentar TABLEUPDATE( ) sin perder datos. De
este modo se asegurará de que la actualización se produce como una
operación de "todo o nada".

Aunque el procesamiento simple de transacciones proporciona operaciones


seguras de actualización de datos en situaciones normales, no ofrece
protección total contra errores del sistema. Si se interrumpe el suministro
eléctrico o el sistema queda bloqueado durante el procesamiento del comando
END TRANSACTION, se puede producir un error en la actualización de datos.

Utilice el código siguiente como plantilla para transacciones:

BEGIN TRANSACTION
* Update records
IF lSuccess = .F. && an error occurs
ROLLBACK
ELSE && commit the changes
* Validate the data
IF && error occurs
ROLLBACK
ELSE
END TRANSACTION
ENDIF
ENDIF

Usar transacciones

Las reglas siguientes se aplican a las transacciones:

 Una transacción comienza con el comando BEGIN TRANSACTION y


termina con el comando END TRANSACTION o ROLLBACK. Una
instrucción END TRANSACTION que no vaya precedida de una
instrucción BEGIN TRANSACTION generará un error.
 Una instrucción ROLLBACK que no vaya precedida de una instrucción
BEGIN TRANSACTION generará un error.
 Una vez comenzada una transacción, permanecerá en vigor hasta que
comience el END TRANSACTION correspondiente (o hasta que se
ejecute un comando ROLLBACK), incluso en programas y funciones, a
menos que se termine la aplicación, lo que producirá una anulación.
 Visual FoxPro utiliza datos almacenados en caché en el búfer de
transacciones antes de utilizar datos del disco para consultas acerca de
los datos relacionados con transacciones. De este modo se asegura la
utilización de los datos más actuales.
 Si la aplicación termina durante una transacción, todas las operaciones
se desharán.
 Una transacción sólo funciona en un contenedor de base de datos.

96
 No es posible utilizar el comando INDEX si sobrescribe un archivo de
índice existente o si hay abierto algún archivo de índice .cdx.
 Las transacciones pertenecen al ámbito de las sesiones de datos.

Las transacciones presentan los comportamientos de bloqueo siguientes:

 En una transacción, Visual FoxPro impone un bloqueo en el momento en


que un comando lo solicita directa o indirectamente. Cualquier comando
de desbloqueo directo o indirecto procedente del sistema o del usuario
se almacena en caché hasta que se complete la transacción mediante
los comandos ROLLBACK o END TRANSACTION.
 Si utiliza un comando de bloqueo como FLOCK( ) o RLOCK( ) en una
transacción, la instrucción END TRANSACTION no liberará el bloqueo.
En ese caso, deberá desbloquear explícitamente todos los bloqueos
realizados en una transacción. Las transacciones que contienen los
comandos FLOCK( ) o RLOCK( ) deben ser lo más breves posible; en
caso contrario, los usuarios podrían encontrar los registros bloqueados
durante mucho tiempo.

Anidar transacciones

Las transacciones anidadas proporcionan grupos lógicos de operaciones de


actualización de tablas que están aislados de los procesos concurrentes. No es
necesario que los pares BEGIN TRANSACTION...END TRANSACTION estén
en la misma función o el mismo procedimiento. Las transacciones anidadas
tienen estas reglas:

 Se pueden anidar hasta cinco pares BEGIN TRANSACTION...END


TRANSACTION.
 Las actualizaciones realizadas en una transacción anidada no se
confirman hasta que se llama a la instrucción END TRANSACTION más
externa.
 En las transacciones anidadas, una instrucción END TRANSACTION
sólo funciona sobre la transacción iniciada por la última instrucción
BEGIN TRANSACTION ejecutada.
 En las transacciones anidadas, una instrucción ROLLBACK sólo
funciona sobre la transacción iniciada por la última instrucción BEGIN
TRANSACTION ejecutada.
 La actualización más interna de una serie de transacciones anidadas
sobre los mismos datos tiene prioridad sobre todas las demás del mismo
bloque de transacciones anidadas.

97
Observe en el ejemplo siguiente que, puesto que los cambios en una
transacción anidada no se escriben en disco, sino en el búfer de transacciones,
la transacción más interna sobrescribirá los cambios realizados en los mismos
campos STATUS de la transacción anterior:

BEGIN TRANSACTION && transaction 1


UPDATE EMPLOYEE ; && first change
SET STATUS = "Contract" ;
WHERE EMPID BETWEEN 9001 AND 10000
BEGIN TRANSACTION && transaction 2
UPDATE EMPLOYEE ;
SET STATUS = "Exempt" ;
WHERE HIREDATE > {^1998-01-01} && overwrites
END TRANSACTION && transaction 2
END TRANSACTION && transaction 1

El siguiente ejemplo de transacción anidada elimina un registro de cliente y


todas las facturas relacionadas. La transacción se deshará si se producen
errores durante un comando DELETE. Este ejemplo muestra la agrupación de
operaciones de actualización de tablas para impedir que las actualizaciones se
completen parcialmente y para evitar conflictos de simultaneidad.

Ejemplo de modificación de registros en transacciones anidadas

Código Comentarios
DO WHILE TXNLEVEL( ) > 0 Limpia el entorno de otras
ROLLBACK transacciones.
ENDDO
CLOSE ALL Establece el entorno para
SET MULTILOCKS ON el almacenamiento en
SET EXCLUSIVE OFF búfer.
OPEN DATABASE test
USE mrgtest1
CURSORSETPROP('buffering',5) Activa el almacenamiento
GO TOP optimista de tablas en
búfer.
REPLACE fld1 WITH "changed" Cambia un registro.
SKIP
REPLACE fld1 WITH "another change" Cambia otro registro.
MESSAGEBOX("modify first field of both" + ;
"records on another machine")
BEGIN TRANSACTION Inicia la transacción 1 e
lSuccess = TABLEUPDATE(.T.,.F.) intenta actualizar todos los
registros modificados que
no están vigentes.

98
IF lSuccess = .F. Si se producen errores en
ROLLBACK la actualización, deshace la
AERROR(aErrors) transacción.
DO CASE Obtiene un error de
CASE aErrors[1,1] = 1539 AERROR( ).
... Determina la causa del
CASE aErrors[1,1] = 1581 error.
... Si un desencadenante ha
CASE aErrors[1,1] = 1582 producido errores,
soluciona el problema.

Si un campo no acepta
valores nulos, soluciona el
problema.
Si se ha infringido una
regla de campo, soluciona
el problema.
CASE aErrors[1,1] = 1585 Si otro usuario ha
nNextModified = getnextmodified(0) modificado un registro,
DO WHILE nNextModified <> 0 localiza el primer registro
GO nNextModified modificado.
RLOCK() Hace un bucle a través de
FOR nField = 1 to FCOUNT() todos los registros
cField = FIELD(nField) modificados, comenzando
con el primero.
if OLDVAL(cField) <> CURVAL(cField) Bloquea cada registro para
asegurarse de que se
puede actualizar.
Comprueba si hay cambios
en cada campo.

Compara el valor
almacenado en búfer con
el valor en disco; a
continuación, muestra un
cuadro de diálogo al
usuario.
nResult = MESSAGEBOX;
("Data was changed " + ;
"by another user — keep"+ ;
"changes?", 4+48, ;
"Modified Record")
IF nResult = 7 Si el usuario responde
TABLEREVERT(.F.) "No", invierte el registro
UNLOCK record nNextModified uno y lo desbloquea.
ENDIF
EXIT Sale del bucle "FOR

99
ENDIF nField...".
ENDFOR
ENDDO Obtiene el siguiente
registro modificado.
BEGIN TRANSACTION Inicia la transacción 2 y
TABLEUPDATE(.T.,.T.) actualiza todos los
END TRANSACTION registros no invertidos que
UNLOCK están en vigor.
Finaliza la transacción 2.
Libera el bloqueo.
CASE aErrors[1,1] = 109 Si el registro está en uso
... por otro usuario, soluciona
CASE aErrors[1,1] = 1583 el problema.
...
CASE aErrors[1,1] = 1884 Si se ha infringido una
... regla de fila, soluciona el
OTHERWISE problema.
MESSAGEBOX( "Unknown error "+;
"message: " + STR(aErrors[1,1])) Si hubo una infracción de
ENDCASE índice único, soluciona el
problema.

De lo contrario, muestra un
cuadro de diálogo al
usuario.
ELSE
END TRANSACTION Termina la transacción 1.
ENDIF

Proteger actualizaciones remotas

Las transacciones pueden protegerle frente a los errores generados por el


sistema durante actualizaciones de datos en tablas remotas. El ejemplo
siguiente utiliza una transacción para ajustar operaciones de escritura de datos
en una tabla remota.

Almacenar datos en búfer

Si desea proteger los datos durante las actualizaciones, utilice búferes. El


almacenamiento en búfer de registros y tablas de Visual FoxPro ayuda a
proteger las operaciones de mantenimiento y actualización de datos en
registros individuales y múltiples registros de datos en entornos multiusuario.
Los búferes pueden comprobar, bloquear y liberar automáticamente registros o
tablas.

100
Mediante el almacenamiento en búfer es posible detectar y resolver fácilmente
conflictos en operaciones de actualización de datos: el registro actual se copia
a una ubicación de memoria o de disco administrada por Visual FoxPro. Los
demás usuarios podrán seguir eniendo t acceso al registro original
simultáneamente. Cuando se desplace fuera del registro o intente actualizarlo
mediante programación, Visual FoxPro intentará bloquear el e r gistro,
comprobará que otros usuarios no hayan realizado cambios y, a continuación,
escribirá las modificaciones. Después de intentar actualizar los datos, deberá
resolver los conflictos que impiden que las modificaciones se escriban en la
tabla original.

Elegir un método de almacenamiento en búfer

Antes de activar el almacenamiento en búfer, evalúe el entorno de datos para


elegir el método de almacenamiento en búfer y las opciones de bloqueo que
mejor se ajusten a las necesidades de edición de la aplicación, los tipos y
tamaños de registros y tablas, y cómo se utiliza y actualiza la información, entre
otros factores. Una vez activado el almacenamiento en búfer, permanecerá en
vigor hasta que lo desactive o hasta que cierre la tabla.

Visual FoxPro dispone de dos tipos de almacenamiento en búfer: registro y


tabla.

Almacenamiento en búfer de registros y tablas de Visual FoxPro

 Para tener acceso, modificar y escribir un registro individual cada vez,


elija el almacenamiento de registros en búfer.

El almacenamiento de registros en búfer proporciona la validación del


proceso adecuado con una repercusión mínima sobre las operaciones

101
de actualización de datos que realizan otros usuarios en un entorno
multiusuario.

 Para almacenar en búfer las actualizaciones a varios registros, elija el


almacenamiento de tablas en búfer.

El almacenamiento de tablas en búfer es el modo más efectivo de


administrar varios registros de una tabla o registros secundarios en una
relación de uno a varios.

 Para proporcionar la máxima protección para los datos existentes, utilice


transacciones de Visual FoxPro.

Las transacciones pueden utilizarse por sí solas, pero obtendrá una


mayor efectividad si las emplea como empaquetadores para comandos
de almacenamiento en búfer de tablas o registros.

Elegir un modo de bloqueo

Visual FoxPro proporciona almacenamiento en búfer en dos modos de bloqueo:


pesimista y optimista. Estas opciones determinan cuándo se bloquean uno o
más registros y cuándo y cómo se liberan.

Almacenamiento en búfer pesimista

El almacenamiento en búfer pesimista impide que otros usuarios de un entorno


multiusuario tengan acceso a un determinado registro o tabla mientras usted
realiza cambios en el mismo. Un bloqueo pesimista proporciona el entorno más
seguro para cambiar registros individuales, aunque puede hacer más lentas las
operaciones del usuario. Este modo de almacenamiento en búfer es bastante
similar al mecanismo de bloqueo estándar de versiones anteriores de FoxPro,
con la ventaja adicional del almacenamiento en búfer de datos integrados.

Almacenamiento en búfer optimista

El almacenamiento en búfer optimista es un modo eficaz de actualizar registros


ya que los bloqueos sólo se realizan en el momento en que se escribe el
registro, minimizando de este modo el tiempo que un único usuario monopoliza
el sistema en un entorno multiusuario. Cuando utilice el almacenamiento en
búfer de registros o tablas para vistas, Visual FoxPro impondrá el bloqueo
optimista.

El valor de la propiedad Buffering, establecido mediante la función


CURSORSETPROP( ) determina los métodos de almacenamiento en búfer y
de bloqueo.

En la tabla siguiente se resumen los valores válidos para la propiedad Buffering:

102
Para activar Utilice este valor
Sin almacenamiento en búfer. El alor
v 1
predeterminado.

Bloqueos pesimistas de registros que bloquean el 2


registro ahora y actualizan cuando el puntero se
mueve o se ejecuta TABLEUPDATE( ).
3
Bloqueos optimistas de registros que esperan hasta
que el puntero se mueve y después bloquean y
actualizan.
4
Bloqueos pesimistas de tablas que bloquean el
registro ahora y actualizan posteriormente al
ejecutarse TABLEUPDATE( ).
Bloqueos optimistas de tablas que esperan hasta 5
TABLEUPDATE( ) para bloquear y actualizar o ls
registros modificados.

El valor predeterminado de Buffering es 1 para las tablas y 3 para las vistas. Si


utiliza el almacenamiento en búfer para tener acceso a datos remotos, la
propiedad Buffering tendrá un valor 3, almacenamiento optimista de filas en
búfer o 5, almacenamiento optimista de tablas en búfer. Para obtener más
información acerca del acceso a datos de tablas remotas, consulte Consultar
múltiples tablas y vistas.

Nota Establezca MULTILOCKS como ON para todos los modos de


almacenamiento en búfer por encima de 1.

Activar el almacenamiento de registros en búfer

Habilite el almacenamiento de registros en búfer mediante la función


CURSORSETPROP( ).

Para activar el bloqueo pesimista de registros en el área de trabajo actual

 Utilice esta función y este valor:

CURSORSETPROP("Buffering", 2)

Visual FoxPro intenta bloquear el registro en la ubicación del puntero. Si el


bloqueo tiene éxito, Visual FoxPro situará el registro en un búfer y permitirá su
modificación. Cuando mueva el puntero de registro o ejecute el comando
TABLEUPDATE( ), Visual FoxPro escribirá el registro almacenado en búfer en
la tabla original.

103
Para activar el bloqueo optimista de registros en el área de trabajo actual

 Utilice esta función y este valor:

CURSORSETPROP("Buffering", 3)

Visual FoxPro escribe en un búfer el registro situado en la ubicación del


puntero y permite modificaciones. Cuando mueva el puntero de registro o
ejecute el comando TABLEUPDATE( ), Visual FoxPro intentará un bloqueo del
registro. Si se produce el bloqueo, Visual FoxPro comparará el valor actual del
registro en el disco con el valor original del búfer. Si ambos valores son iguales,
las modificaciones se escribirán en la tabla original; si los valores son distintos,
Visual FoxPro generará un error.

Activar el almacenamiento de tablas en búfer

Habilite el almacenamiento de tablas en búfer mediante la función


CURSORSETPROP( ).

Para activar el bloqueo pesimista de múltiples registros en el área de


trabajo actual

 Utilice esta función y este valor:

CURSORSETPROP("Buffering", 4)

Visual FoxPro intenta bloquear el registro en la ubicación del puntero. Si el


bloqueo tiene éxito, Visual FoxPro situará el registro en un búfer y permitirá su
modificación. Utilice el comando TABLEUPDATE( ) para escribir en la tabla
original los registros almacenados en búfer.

Para activar el bloqueo optimista de múltiples registros en el área de


trabajo actual

 Utilice esta función y este valor:

CURSORSETPROP("Buffering", 5)

Visual FoxPro escribe los registros en un búfer y permite modificarlos hasta que
se ejecute un comando TABLEUPDATE( ). A continuación, Visual FoxPro
llevará a cabo la siguiente secuencia en cada registro del búfer:

 Intenta un bloqueo en cada registro modificado.


 Cuando realiza el bloqueo, compara el valor actual de cada registro del
disco con el valor original del búfer.
 Escribe las modificaciones en la tabla original si la comparación indica
que ambos valores son iguales.
 Genera un error si los valores son distintos.

104
Cuando se activa el almacenamiento de tablas en búfer, Visual FoxPro sólo
intentará realizar actualizaciones después de que se ejecute el comando
TABLEUPDATE( ).

Agregar y eliminar registros de búferes de tablas

Puede anexar y eliminar registros mientras está activado el almacenamiento de


tablas en búfer: los registros anexados se agregan al final del búfer. Para tener
acceso a todos los registros del búfer, incluidos los registros anexados, utilice
la función RECNO( ). La función RECNO( ) devuelve números negativos
secuenciales para los registros que usted anexe a un búfer de tabla. Por
ejemplo, si inicia el almacenamiento de tablas en búfer, modifica los registros 7,
8 y 9, y a continuación anexa tres registros, el búfer contendrá valores
RECNO( ) de 7, 8, 9, – 1, – 2 y – 3.

Nota Las tablas con valores de campo auto incremental agrega registros con
búfer de tabla aproximadamente un 35% más lento que las tablas sin valores
de campo auto incremental, lo cual podría afectar el rendimiento. Cuando utilice
búfer de tabla, la cabecera de la tabla se bloquea cuando se agrega el registro.

Búfer después de modificar y anexar registros

Sólo podrá quitar del búfer registros anexados si utiliza el comando


TABLEREVERT( ). Para cualquier registro anexado, TABLEUPDATE( ) y
TABLEREVERT( ) eliminan el valor negativo de RECNO( ) para ese registro y
mantienen la secuencia.

Búfer después de modificar, eliminar un registro anexado y anexar otro

Mientras utiliza un búfer de tabla, puede usar el comando GO con el valor


negativo de RECNO( ) para tener acceso a un determinado registro anexado.
Por ejemplo, utilizando el ejemplo anterior, puede escribir:

GO 7 && se mueve al primer registro en búfer


GO -3 && se mueve al sexto registro en búfer (tercero agregado)

Agregar registros a un búfer de tabla

 Utilice el comando APPEND o APPEND BLANK después de habilitar el


almacenamiento de tablas en búfer.

Los registros anexados tienen números de RECNO( ) negativos y secuenciales


en sentido ascendente.

Para quitar un registro anexado de un búfer de tabla

1. Utilice el comando GO con un valor negativo para situar el puntero de


registro en el registro que desea eliminar.

105
2. Utilice el comando DELETE para marcar el registro para su eliminación.
3. Utilice el comando TABLEREVERT( ) para quitar el registro del búfer.

Nota La función TABLEREVERT( ) también afecta al estado de las filas


eliminadas o modificadas.

Para quitar todos los registros anexados de un búfer de tabla

 Utilice TABLEREVERT( ) con un valor True (.T.).

TABLEREVERT( ) quita de un búfer de tabla los registros anexados sin escribir


los registros en la tabla. TABLEUPDATE( ) escribe en una tabla todos los
registros que están almacenados en búfer, aunque se hayan marcado para su
eliminación.

SELECT - SQL (Comando)

Recupera datos de una o más tablas. El comando SELECT SQL está incluido
en Visual FoxPro como cualquier otro comando de Visual FoxPro. Cuando
utilice SELECT para hacer una consulta, Visual FoxPro interpreta la consulta y
recupera los datos especificados de las tablas. Puede crear un consulta
SELECT en la siguiente forma:

 Ventana de Comandos
 Programa de Visual FoxPro como con cualquier otro comando de Visual
FoxPro
 Diseñador de consultas

SELECT [ALL | DISTINCT] [TOP nExpr [PERCENT]] [Alias.] Select_Item


[[AS] Column_Name] [, [Alias.] Select_Item [[AS] Column_Name] ...] FROM
[FORCE] [DatabaseName!] Table [[AS] Local_Alias] [ [INNER | LEFT [OUTER] |
RIGHT [OUTER] | FULL [OUTER] JOIN DatabaseName!] Table [[AS]
Local_Alias] [ON JoinCondition ...] [[INTO Destination] | [TO FILE FileName
[ADDITIVE] | TO PRINTER [PROMPT] | TO SCREEN]] [PREFERENCE
PreferenceName] [NOCONSOLE] [PLAIN] [NOWAIT] [WHERE JoinCondition
[AND JoinCondition ...] [AND | OR FilterCondition [AND | OR FilterCondition ...]]]
[GROUP BY GroupColumn [, GroupColumn ...]] [HAVING FilterCondition]
[UNION [ALL] SELECTCommand] [ORDER BY Order_Item [ASC | DESC] [,
Order_Item [ASC | DESC] ...]]

106
Parámetros
SELECT
Especifica los campos, constantes y expresiones que se mostrarán en el
resultado de la consulta.
ALL
De forma predeterminada, se muestran todas las filas del resultado de la
consulta.
DISTINCT
Excluye duplicados de cualquier fila del resultado de la consulta. Puede
utilizar DISTINCT únicamente una vez por cada cláusula SELECT.

Visual FoxPro no admite el uso de una cláusula DISTINCT en una


instrucción SELECT SQL que contenga campos memo o general. En su
lugar, puede ajustar un campo Memo en un expresión dentro de una
función como PADR( ) o ALLTRIM( ). Para más información, consulte
PADL( ) | PADR( ) | PADC( ) (Funciones) y ALLTRIM( ) (Función).

TOP nExpr [PERCENT]


Especifica que el resultado de la consulta contenga un número
determinado de filas o un porcentaje de filas en el resultado de la
consulta. Puede especificar desde 1 a 32.767 filas. Si se ni cluye la
palabra clave PERCENT, se redondeará al número entero más alto el
número de columnas devuelto en el resultado. Los valores permitidos
para nExpr cuando se incluye la palabra clave PERCENT son de 0,01 a
99,99.

Las filas de valores idénticos para las columnas especificadas en la


cláusula ORDER BY se incluyen en el resultado de la consulta. Por lo
tanto, si especifica 10 para nExpr, el resultado de la consulta podrá
obtener más de 10 filas, si hay más de 10 filas con valores idénticos
para las columnas especificadas en la cláusula ORDER BY.

Es necesario incluir una cláusula ORDER BY si incluye la cláusula TOP.


La cláusula ORDER BY especifica las columnas en las que la cláusula
TOP determinará el número de filas que se va a incluir en el resultado de
la consulta.

[Alias.] Select_Item
Califica nombres de elementos coincidentes. Select_Item especifica un
elemento que se incluirá en el resultado de la consulta. Un elemento
puede ser uno de los siguientes:

 El nombre de un campo de una tabla de la cláusula FROM.


 Una constante, especificando que el mismo valor constante debe
aparecer en cada fila del resultado de la consulta.

107
 Una expresión que puede ser el nombre de una función definida
por el usuario (FDU).

Para más información acerca de utilizar funciones definidas por el


usuario, vea Funciones definidas por el usuario con SELECT en la
seccion Observaciones.

Cada elemento que especifique con Select_Item genera una columna de


los resultados de la consulta.

Si dos o más elementos tienen el mismo nombre, incluya el alias de la


tabla y un punto antes del nombre del elemento para impedir la
duplicación de las columnas.

[AS] Column_Name
Especifica el título de una columna en el resultado de la consulta.
Column_Name puede ser una expresión, pero no puede contener
caracteres (por ejemplo, espacios) que no estén permitidos para
nombres de campos de tablas.

Esta opción resulta muy útil cuando Select_Item es una expresión o


contiene una función de campo y desea dar un nombre significativo a la
columna.
FROM [FORCE] DatabaseName!
Indica las tablas que contienen los datos que ha obtenido la consulta.

FORCE especifica que las tablas se combinen en el orden de aparición


en la cláusula FROM. Si se omite FORCE, Visual FoxPro intentará
optimizar la consulta. Sin embargo, es posible que la consulta se ejecute
más rápido si se incluye la palabra clave FORCE para desactivar la
optimización de consultas de Visual FoxPro.

DatabaseName! especifica el nombre de una base de datos inactiva que


contiene la tabla. Es necesario incluir el nombre de la base de datos que
contiene la tabla en caso de que no sea la base de datos activa. Incluya
el delimitador signo de exclamación (!) después del nombre de la base
de datos y antes del nombre de la tabla.

[[AS] Local_Alias]
Especifica un nombre temporal para la tabla indicada en Table. Si
especifica un alias local, debe utilizar el alias local en lugar del nombre
de la tabla en toda la instrucción SELECT.

INNER JOIN especifica que el resultado de la consulta contenga sólo


filas en una tabla con la que coincidan una o varias filas de otra tabla.

LEFT [OUTER] JOIN especifica que el resultado de la consulta contenga


todas las filas de la tabla a la izquierda de la palabra clave JOIN y sólo

108
las filas que coincidan procedentes de la tabla a la derecha de la palabra
clave JOIN. La palabra clave OUTER es opcional; se puede incluir para
resaltar que se ha creado una combinación externa.

RIGHT [OUTER] JOIN especifica que el resultado de la consulta


contenga todas las filas de la tabla a la derecha de la palabra clave JOIN
y sólo las filas que coincidan de la tabla a la izquierda de la palabra
clave JOIN. La palabra clave OUTER es opcional; se puede incluir para
resaltar que se ha creado una combinación externa.

FULL [OUTER] JOIN especifica que el resultado de la consulta contenga


todas las filas, coincidan o no, de ambas tablas. La palabra clave
OUTER es opcional; se puede incluir para resaltar que se ha creado una
combinación externa.

Para más información acerca de combinaciones, vea Combinaciones


en la sección Observaciones.

ON Join Condition especifica las condiciones según las cuales se


combinan las tablas.

INTO Destination

Especifica donde almacenar los resultados de la consulta. Destination


puede ser uno de los siguientes:

 ARRAY ArrayName, que almacena los resultados de la consulta


en una matriz de variable de memoria.

Si la consulta selecciona 0 registros, la matriz no se creará.

 CURSOR CursorName [NOFILTER | READWRITE], que


almacena los resultados de una consulta en un cursor.

Incluya NOFILTER para crear un cursor que se pueda usar en


consultas posteriores. Para más información acerca de
NOFILTER, vea la sección Observaciones.

La cláusula READWRITE especifica que el cursor es temporal y


se puede modificar. Si la tabla o ta blas origen utilizan
autoincremento, la configuración no se hereda por el cursor
READWRITE.

DBF | TABLE TableName[DATABASE DatabaseName [NAME


LongTableName]] almacena los resultados de una consulta en
una tabla.

109
Incluya DATABASE DatabaseName para especificar una base de
datos a la que se agregará la tabla.

Incluya NAME LongTableName para especificar un nombre largo


para la tabla. Los nombres largos pueden contener un máximo de
128 caracteres y se pueden utilizar en lugar de nombres de
archivo cortos en la base de datos.

Si no incluye la cláusula INTO, los resultados de la consulta se


mostrarán en la ventana Examinar. También puede utilizar la cláusula
TO FILE para dirigir los resultados de la consulta a la impresora o un
archivo.

TO FILE FileName [ADDITIVE] | TO PRINTER [PROMPT] | TO SCREEN


Puede dirigir los resultados de la consulta a la impresora o un archivo.

ADDITIVE anexa los resultados de la consulta al contenido existente del


archivo de texto especificado en TO FILE FileName.

TO PRINTER [PROMPT] dirige los resultados de la consulta a una


impresora. Utilice la cláusula PROMPT opcional para mostrar un cuadro
de diálogo antes de que empiece la impresión. En este cuadro de
diálogo puede modificar la configuración de la impresora. Las opciones
de configuración de la impresora que puede ajustar dependen del
controlador de impresora que tenga instalado actualmente. Coloque
PROMPT justo después de TO PRINTER.

TO SCREEN dirige los resultados de la consulta a la ventana principal


de Visual FoxPro o a una ventana activa definida por el usuario.

PREFERENCE PreferenceName
Si el resultado de una consulta se envía a una ventana Examinar,
guarda los atributos y opciones de la ventana Examinar para utilizarlos
después. Para más información acerca de como funcion a
PREFERENCE vea la sección Observaciones.
NOCONSOLE
Impide que el resultado de la consulta se envíe a un archivo, a la
impresora o a la ventana principal de Visual FoxPro.
PLAIN
Impide que aparezcan los encabezados de las columnas al mostrar los
resultados de la consulta. PLAIN puede utilizarse tanto si está presente
una cláusula TO como si no. Si se incluye una cláusula INTO, se pasará
por alto PLAIN.
NOWAIT
Continúa la ejecución del programa después de abrir la ventana
Examinar y de dirigir a ella los resultados de la consulta. El programa no
esperará a que la ventana Examinar se cierre, sino que continuará con
la ejecución de la línea de programa inmediatamente siguiente a la

110
instrucción SELECT. Para una explicación sobre como puede utilizar
NOWAIT, vea la sección Observaciones.
WHERE JoinCondition
Especifica que Visual FoxPro sólo debe incluir en los resultados de la
consulta los registros que satisfagan los criterios especific ados.
JoinCondition especifica los campos que vinculan las tablas de al
cláusula FROM. Para más información acerca de especificar
condiciones de combinación, vea la sección Observaciones.

WHERE admite el operador ESCAPE para JoinCondition, permitiendo


realizar consultas con significado sobre datos que contengan caracteres
comodín _ y % de SELECT - SQL.. La cláusula ESCAPE le permite
especificar que se traten los caracteres comodín de SELECT - SQL
como si fueran caracteres literales. En la cláusula ESCAPE se
especifica un carácter, que si se coloca inmediatamente antes del
carácter comodín, indica que se tratará al carácter comodín como a un
carácter literal.

FilterCondition
Especifica los criterios que deben satisfacer los registros para ser
incluidos en los resultados de la consulta. Una consulta puede incluir
tantas condiciones de filtro como desee, conectadas con el operador
AND y OR. También puede utilizar el operador NOT para invertir el valor
de una expresión lógica o utilizar EMPTY( ) para comprobar si hay
campos vacíos.

El comando SELECT SQL admite "<field> IS / IS NOT NULL" en la


condición de filtro. Para aprender como utilizar FilterCondition, vea la
sección Ejemplos.

GROUP BY GroupColumn [, GroupColumn ...]


Agrupa las filas de la consulta basándose en los valores de una o más
columnas. GroupColumn puede ser el nombre de un campo normal de
una tabla, o un campo que incluya una función de campo SQL o una
expresión numérica que indique la posición de la columna en la tabla de
resultados (la columna más a la izquierda tiene el número 1).
HAVING FilterCondition
Especifica una condición de filtro que los grupos deben satisfacer para
quedar incluidos en el resultado de la consulta. Puede incluir tantas
condiciones de filtro como desee, conectadas con los operadores AND u
OR. También puede utilizar NOT para invertir el valor de una expresión
lógica. Puede utilizar funciones locales de campos y alias en la cláusula
HAVING. Para más información sobre las funciones de campo que
puede utilizar, vea la sección Observaciones.

FilterCondition no puede contener una subconsulta.

111
Puede utilizar una instrucción SELECT conteniendo una cláusula
HAVING sin incluir una cláusula GROUP BY si SELECT no contiene
funciones de agrupación. La cláusula HAVING sin una cláusula GROUP
BY actúa como una cláusula WHERE. Si la cláusula HAVING no
contiene funciones de campo, utilice la cláusula WHERE para acelerar el
rendimiento.

La cláusula HAVING debe aparecer antes de una cláusula INTO porque


de lo contrario se producirá un error de sintaxis.

[UNION [ALL] SELECTCommand]


Combina el resultado final de un SELECT con el resultado final de otro
SELECT. De forma predeterminada, UNION comprueba el resultado
combinado y elimina las filas duplicadas. Puede utilizar paréntesis para
combinar varias cláusulas UNION.

Puede utilizar la cláusula UNION para simular una combinación externa.

ALL impide que UNION elimine filas duplicadas de o


l s resultados
combinados.

Cuando una de las columnas tiene tipo Memo o General, las uniones de
diferentes tipos de columna no está permitida.

En versiones anteriores a Visual FoxPro 8.0, necesitaba realizar una


conversión explícita cuando realizaba operaciones UNION entre dos
campos de diferente tipo. Visual FoxPro ahora admite la conversión
implícita de tipo de datos para los tipos de datos que lo admiten. Para
más detalles acerca de la conversión implícita de tipo de datos y la
precedencia de tipo de datos, las reglas para la cláusula UNION y otra
información, vea Conversión y precedencia de tipo de dato en la
sección Observaciones.

ORDER BY Order_Item [ASC | DESC]


Ordena el resultado de la consulta basándose en los datos de una o
varias columnas. Cada Order_Item debe corresponder a una columna de
resultados de la consulta y puede ser uno de los siguientes:

 Un campo de una tabla FROM que también es un elemento de


selección en la cláusula principal SELECT (no en una
subconsulta).
 Una expresión numérica que indica la ubicación de la columna en
la tabla de resultados. (La columna de la izquierda es la número
1.)

ASC especifica un orden ascendente para los resultados de la consulta,


de acuerdo con el elemento o los elementos de orden, y es el valor
predeterminado para ORDER BY.

112
DESC especifica un orden descendente para los resultados de la
consulta.

Observaciones

Si no hay una tabla abierta cuando se usa la cláusula FROM, Visual FoxPro
muestra el cuadro de diálogo Abrir para que se pueda especificar la ubicación
del archivo. Una vez abierta, la tabla permanece abierta después de completar
la consulta.

Cuando utilice la cláusula CURSOR en el parámetro Destination, si especifica


el nombre de una tabla abierta, Visual FoxPro generará un mensaje de error.
Después de ejecutar SELECT, el cursor temporal permanecerá abierto y estará
activo, pero solamente para lectura a menos que especifique la opción
READWRITE. Cuando cierre este cursor temporal, se borrará. Los cursores
pueden existir como un archivo temporal en la unidad especificada por
SORTWORK.

Cuando utilice la cláusula CURSOR en el parámetro Destination, ahora puede


usar NOFILTER para crear un cursor que pueda utilizarse en consultas
posteriores. En versiones anteriores de Visual FoxPro, era necesario incluir una
expresión o una constante adicional como un filtro para crear un cursor
utilizable en consultas posteriores. Por ejemplo, la adición de un valor lógico
verdadero como una expresión de filtro creaba una consulta que podía
utilizarse en consultas posteriores:

SELECT *, .T. FROM customers INTO CURSOR myquery

Si se incluye NOFILTER, es posible que disminuya el rendimiento de la


consulta, puesto que se crea una tabla temporal en el disco. Cuando se cierre
el cursor se eliminará del disco la tabla temporal.

Cuando utilice la cláusula DBF | TABLE en el parámetro Destination, si


especifica una tabla que ya esté abierta y SET SAFETY está en OFF, Visual
FoxPro sobrescribirá la tabla sin previo aviso. Si no ha especificado ninguna
extensión, Visual FoxPro asignará la extensión .DBF a la tabla. La tabla
permanecerá abierta y activa después de ejecutar SELECT.

Si incluye las cláusulas INTO y TO en la misma consulta, Visual FoxPro ignora


la cláusula TO. Si incluye una cláusula TO pero no una cláusula INTO, puede
dirigir el resultado de la consulta a un archivo de texto ASCII llamado FileName,
a la impresora o a la ventana principal de Visual FoxPro.

La cláusula PREFERENCE guarda indefinidamente en el archivo de recursos


FoxUser.dbf, los atributos o preferencias. Las preferencias se pueden
recuperar en cualquier momento. Ejecutar SELECT con PREFERENCE

113
PreferenceName la primera vez, crea las preferencias. Ejecutar después
SELECT con el mismo nombre para preferencia restaura la ventana Examinar
con las preferencias establecidas. Cuando la ventana Examinar se cierra, las
preferencias se actualizan. Si sale de una ventana Examinar presionando
CTRL+Q+W, no se guardan en el archivo de recursos los cambios que haya a
la ventana.

Como un ejemplo de la forma en que puede utilizar la cláusula NOWAIT,


cuando incluye la cláusula TO SCREEN para dirigir la salida a la ventana
principal de Visual FoxPro o a una ventana definida por el usuario, la salida se
detiene cuando la ventana se llena con los resultados de la consulta. Para ver
el siguiente conjunto de resultados de la consulta, presione cualquier tecla. Si
incluye NOWAIT, los resultados de la consulta se desplazan fuera de la
ventana sin esperar que se presione una tecla. Visual FoxPro ignora NOWAIT
si se incluye con la cláusula INTO.

Si se incluye la función EVALUATE( ) en la cláusula WHERE de una consulta


SQL, podrían devolverse datos incorrectos.

Si incluye más de una tabla en una consulta, deberá especificar una condición
de combinación para cada tabla después de la primera.

Nota El número máximo de combinaciones en una instrucción SELECT es de


nueve (9).

Las condiciones de combinación múltiples deben conectarse mediante el


operador AND. Cada condición de combinación tiene la forma siguiente:

FieldName1 Comparison FieldName2

FieldName1 es el nombre de un campo de una tabla, FieldName2 es el nombre


de un campo de otra tabla y Comparison es uno de los operadores siguientes:

Operador Comparación
= Igual
== Exactamente igual
LIKE SQL LIKE
<>, !=, # Distinto de
> Mayor que
>= Mayor o igual que
< Menor que
<= Menor o igual que

Cuando utiliza el operador = con cadenas, actúa de forma distinta dependiendo


del ajuste de SET ANSI. Cuando SET ANSI está desactivado, Visual FoxPro
trata las comparaciones de cadenas en la forma habitual en Xbase. Cuando
SET ANSI está activado, Visual FoxPro sigue las normas ANSI para las

114
comparaciones de cadenas. Vea SET ANSI y SET EXACT para obtener
información adicional acerca de cómo realiza Visual FoxPro las comparaciones
de cadenas.

Las siguientes funciones de campo están disponibles para ser utilizadas con un
elemento seleccionado que sea un campo o una expresión que incluya a un
campo:

 AVG(Select_Item), que promedia una columna de datos numéricos.


 COUNT(Select_Item), que cuenta el número de ele mentos
seleccionados en una columna. COUNT(*) cuenta el número de filas en
el resultado de la consulta.
 MIN(Select_Item), que determina el menor valor de Select_Item en una
columna.
 MAX(Select_Item), que determina el mayor valor de Select_Item en una
columna.
 SUM(Select_Item), que proporciona el total de la suma de una columna
de datos numéricos.

No se pueden anidar las funciones de campo.

Las cláusulas UNION siguen las reglas siguientes:

 No puede utilizar UNION para combinar subconsultas.


 Los resultados de ambos SELECT deben tener el mismo número de
columnas.
 Cuando dos columnas con diferentes tipos de datos forman parte de una
operación UNION, el tipo de dato con la menor precedencia se convierte
al tipo de dato con la mayor precedencia. Para más información, vea la
sección "Conversión y precedencia de tipos de datos".
 Únicamente el SELECT final puede tener una cláusula ORDER BY, que
debe referirse a las columnas de resultados por su número. Si se incluye
otra cláusula ORDER BY, afectará al resultado completo.

Si no especifica un orden en la cláusula ORDER BY, los resultados de la


consulta no aparecen ordenados.

Cuando ejecuta SET TALK ON y ejecuta SELECT, Visual FoxPro muestra la


duración de la consulta y el número de registros del resultado. _TALLY
contiene el número de registros del resultado de la consulta.

SELECT no respeta la condición de filtro actual especificada con SET FILTER.

Nota Una subconsulta, a la que se hace referencia en los argumentos


siguientes, es un comando SELECT dentro de otro SELECT y debe incluirse
entre paréntesis. Puede tener hasta dos subconsultas al mismo nivel (no
anidadas) en la cláusula WHERE (consulte esta sección de los argumentos).
Las subconsultas pueden contener condiciones de combinación múltiples.

115
Cuando se obtiene el resultado de una consulta, las columnas se denominan
según las siguientes reglas:

 Si un elemento seleccionado Select_Item es un campo con un nombre


único, el nombre de la columna de resultados es el nombre del campo.
 Si hay más de un elemento seleccionado Select_Item con el mismo
nombre, se anexarán un signo de subrayado y una letra al nombre de la
columna. Por ejemplo, si una tabla llamada Customer tiene un campo
llamado STREET, y una tabla llamada Employees también tiene un
campo llamado STREET, las columnas de resultado se llamarán
Extension_A y Extension_B (STREET_A y STREET_B). En el caso de
un elemento seleccionado con un nombre de 10 caracteres, se truncará
el nombre para agregar el símbolo de subrayado y la letra. Por ejemplo,
DEPARTMENT se convertiría en DEPARTME_A.
 Si un elemento seleccionado Select_Item es una expresión, su columna
de resultado se llamará EXP_A. Cualquier otra expresión recibirá el
nombre de EXP_B, EXP_C, y así sucesivamente.
 Si un elemento seleccionado Select_Item contiene una función de
campo como, por ejemplo, COUNT( ), la columna de resultado se
llamará CNT_A. Si otro elemento seleccionado contiene SUM( ), su
columna de resultado se llamará SUM_B.

Funciones definidas por el usuario con SELECT Aunque la utilización de


funciones definidas por el usuario en la cláusula SELECT ofrece unas ventajas
evidentes, también debería tener en cuenta las siguientes limitaciones:

 Es posible que la velocidad de las operaciones con SELECT se vea


limitada por la velocidad a la que se ejecutan las funciones definidas por
el usuario. Las manipulaciones de un gran volumen que impliquen
funciones definidas por el usuario se pueden realizar mejor utilizando
funciones API y funciones definidas por el usuario escritas en C o en
lenguaje ensamblador.
 No se puede suponer nada acerca de la entrada/salida (E/S) de Visual
FoxPro ni del entorno de la tabla en funciones definidas por el usuario
invocadas a partir de SELECT. Generalmente no se puede saber qué
área de trabajo se ha seleccionado, el nombre de la tabla actual, ni los
nombres de los campos que se están procesando. El valor de estas
variables depende del lugar específico, en el proceso de optimización,
en el que se invoque la función definida por el usuario.
 En funciones definidas por el usuario invocadas desde SELECT, no es
seguro cambiar la E/S de Visual FoxPro ni el entorno de la tabla. En
general, los resultados son impredecibles.
 La única forma segura de pasar valores a funciones definidas por el
usuario invocadas desde SELECT es por medio de la lista de
argumentos pasada a la función al invocarla.

116
 Si prueba y descubre una manipulación teóricamente prohibida que
funciona correctamente en una versión determinada de FoxPro, eso no
significa que también funcione en versiones posteriores.

Fuera de estas limitaciones, a l s funciones definidas por el usuario son


aceptables en la cláusula SELECT. Sin embargo, recuerde que la utilización de
SELECT puede reducir el rendimiento. Para aprender como puede utilizar
SELECT con funciones definidas por el usuario, vea la sección Ejemplos.

Combinaciones Visual FoxPro admite sintaxis de combinación de 1992 SQL


ANSI, lo que le permite crear consultas que vinculen las filas en dos o más
tablas mediante la comparación de los valores de campos especificados. Por
ejemplo, una combinación interna selecciona filas procedentes de dos tablas
sólo cuando los valores de los campos combinados son iguales. Visual FoxPro
admite combinaciones anidadas.

Como SQL está basado en la teoría matemática de conjuntos, cada tabla se


puede representar como un círculo. La cláusula ON que especifica las
condiciones de la combinación determina el punto de intersección, que
representa el conjunto de filas que coinciden. En el caso de una combinación
interna, la intersección tendrá lugar en el interior o en una parte “interna” de los
dos círculos. Una combinación externa incluye tanto las filas coincidentes que
se han encontrado en la sección de intersección interna de las tablas, como las
filas de la parte externa del círculo, a la izquierda o a la derecha de la
intersección.

Nota Tenga presente la siguiente información a la hora de crear condiciones


de combinación:

 Si incluye dos tablas en una consulta y no especifica una condición de


combinación, cada registro de la primera tabla se combinará con cada
registro de la segunda tabla mientras se cumplan las condiciones del
filtro. Una consulta de este tipo puede producir unos resultados muy
largos.
 Sea prudente al utilizar, en condiciones de combinación, funciones como
DELETED( ), EOF( ), FOUND( ), RECCOUNT( ) y RECNO( ), que
aceptan un área de trabajo o un alias opcional. La inclusión de un alias o
de un área de trabajo en estas funciones puede producir resultados
inesperados. SELECT no utiliza sus áreas de trabajo; realiza lo mismo
que USE ... AGAIN. Las consultas de una sola tabla que utilizan estas
funciones sin un área de trabajo o un alias opcional, devolverán
resultados correctos. De todas formas, las consultas de varias tablas
que utilicen dichas funciones (incluso sin un área de trabajo o un alias
opcional) pueden devolver resultados inesperados.
 Tenga cuidado al combinar tablas que contengan campos vacíos, ya que
Visual FoxPro establece coincidencias entre los campos vacíos. Por
ejemplo, si combina CUSTOMER.ZIP e INVOICE.ZIP, y CUSTOMER

117
contiene 100 códigos postales vacíos e INVOICE contiene 400 códigos
postales vacíos, el resultado de la consulta contendrá 40.000 registros
más, como resultado de los campos vacíos. Use la función EMPTY( )
para eliminar los registros vacíos del resultado de la consulta.
 El número de combinaciones que puede utilizar está limitado. Por cada
instrucción SELECT se admiten nueve combinaciones como máximo.

Conversión y precedencia de tipos de datos Las conversiones explícitas


requieren que utilice funciones de conversión de Visual FoxPro, como CTOD( ),
mientras que las conversiones implícitas no requieren que utilice funciones de
conversión. Visual FoxPro admite la conversión implícita de datos que lo
admiten. Cuando Visual FoxPro combina dos columnas de tipos de datos
diferentes en una operación SELECT...UNION, los tipos de datos con menor
precedencia se convierten a los tipos de datos con mayor precedencia. Para
propiedades de campo, NULL tiene mayor precedencia que NOT NULL.

La siguiente tabla muestra todos los tipos de conversión implícita y explícita,


permitidos para tipos de datos de tablas de Visual FoxPro.

Tipo de dato Comvesión implícita Conversión explícita


Character Character (Binary) CTOD( ), CTOT( ), VAL( ),
CTOBIN( )
Character
(Binary)
Currency MTON( )
Date DateTime DTOC( ), DTOS( ), DTOT( )
DateTime TTOC( ), TTOD( )
Double STR( ), VAL( )
Float Numérico NTOM( ), STR( ), INT( )
Integer Numérico, Float, Double,BINTOC( )
Currency
Logical
Numérico Float NTOM( ), STR( ), INT( )

La siguiente tabla ilustra los resultados de la conversión implícita en una


operación SELECT...UNION de dos campos.

Tipo de dato 1 Tipo de dato 2 Tipo de datos esperado


Character (N) Character (X) Character (MAX(N,X))
Character (N) Character Binary (X) Character Binary (MAX(N,X))
Character (N) Memo Memo
Character Binary Character Binary (X) Character Binary (MAX(N,X))
(N)
Character Binary Memo Memo
(N)

118
Currency Currency Currency
Date Date Date
Date DateTime DateTime
DateTime DateTime DateTime
Double (N) Float (X,Y) Float (MAX(MAX(8,Y),2))
Double (N) Integer Double (N)
Double (N) Numérico (X,Y) Double (MAX(MAX(8,Y),2))
Double (X) Double (Y) Double (MAX(X,Y))
Float (N,M) Double (X) Float (20, MAX(M,X))
Float (N,M) Float (X,Y) Float (MAX(N,M), MAX(X,Y))
Float (N,M) Numérico (X,Y) Float (MAX (N,X),
MAX(M,Y))
Integer Currency Currency
Integer Double (X) Double (X)
Integer Float (X,Y) Float (MAX(11,X), Y)
Integer Integer Integer
Integer Numérico (X,Y) Numérico (MAX(11,X), Y)
Logical Logical Logical
Numérico (N,M) Double (X) Numérico (20, MAX(M,X))
Numérico (N,M) Float (X,Y) Float (MAX(N,X), MAX(M,Y))
Numérico (N,M) Numérico (X,Y) Numérico (MAX(N,X),
MAX(M,Y))

Ejemplos

Los siguientes ejemplos ilustran como el parámetro FilterCondition puede tomar


una de varias formas:

Ejemplo 1

En el ejemplo 1 se muestra FilterCondition como FieldName1 Comparison


FieldName2

customer.cust_id = orders.cust_id
Ejemplo 2

En el ejemplo 2 se muestra FilterCondition como FieldName Comparison


Expression

payments.amount >= 1000


Ejemplo 3

En el ejemplo 3 se muestra FilterCondition como FieldName Comparison ALL


(Subquery)

119
Cuando la condición de filtro incluye ALL, el campo debe cumplir la condición
de comparación para todos los valores generados por la subconsulta antes de
que se incluya el registro en el resultado de la consulta.

company < ANY (SELECT company FROM customer WHERE country = "UK")
Ejemplo 4

En el ejemplo 4 se muestra FilterCondition como FieldName Comparison ANY |


SOME (Subquery)

Cuando la condición de filtro incluye ANY o SOME, el campo debe cumplir la


condición de comparación en al menos uno de los valores generados por la
subconsulta.

company < ANY (SELECT company FROM customer WHERE country = "UK")
Ejemplo 5

En el ejemplo 5 se muestra FilterCondition como FieldName [NOT] BETWEEN


Start_Range AND End_Range

Este ejemplo comprueba si los valores del campo están dentro de un intervalo
de valores especificado.

customer.postalcode BETWEEN 90000 AND 99999


Ejemplo 6

En el ejemplo 6 se muestra FilterCondition como [NOT] EXISTS (Subquery)

Este ejemplo comprueba si al menos una línea cumple los criterios de la


subconsulta. Cuando la condición de filtro incluye EXISTS, la condición de filtro
se evalúa como verdadero (.T.) a no ser que la subconsulta sea un conjunto
vacío.

EXISTS ;
(SELECT * FROM orders WHERE customer.postalcode = orders.postalcode)
Ejemplo 7

En el ejemplo 7 se muestra FilterCondition como FieldName [NOT] IN


Value_Set

Cuando una condición de filtro incluye IN, el campo debe contener uno de los
valores antes de que el registro se incluya en los resultados de la consulta.

customer.postalcode NOT IN ("98052","98072","98034")

Nota Puede tener un máximo de 24 elementos en el conjunto de valores. Si el


conjunto contiene más valores, la instrucción SELECT-SQL fallará diciendo que
es un resultado muy complejo.

120
Ejemplo 8

En el ejemplo 8 se muestra FilterCondition como FieldName [NOT] IN


(Subquery)

Aquí, el campo debe contener uno de los valores devueltos por la subconsulta
antes de que su registro se incluya en los resultados de la consulta.

customer.cust_id IN ;
(SELECT orders.cust_id FROM orders WHERE orders.city="Seattle")

Ejemplo 9

En el ejemplo 9 se muestra FilterCondition como FieldName [NOT] LIKE


cExpression

customer.country NOT LIKE "UK"

Esta condición de filtro busca cada uno de los campos que coinciden con
cExpression. Puede utilizar el signo de porcentaje (%) y subrayado ( _ ) como
parte de cExpression. El signo de porcentaje representa a cualquier secuencia
de caracteres desconocidos en la cadena. El subrayado representa un solo
carácter desconocido en la cadena.

Los siguientes ejemplos ilustran como utilizar funciones definidas por el usuario
con el comando SELECT SQL:

Ejemplos

Los siguientes ejemplos ilustran la utilización de las funciones definidas por el


usuario con SELECT - SQL:

Ejemplo 1

En el ejemplo 1 se muestran los nombres de todas las compañías en customer


(un campo de una tabla).

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT customer.company ;
FROM customer

121
Ejemplo 2

El ejemplo 2 muestra el contenido de tres campos de dos tablas y combina las


dos tablas basándose en el campo cust_id. Utiliza alias locales para ambas
tablas.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT x.company, y.order_date, y.shipped_on ;
FROM customer x, orders y ;
INNER JOIN orders y ON x.cust_id = y.cust_id

Ejemplo 3

El ejemplo 3 muestra únicamente registros con datos únicos en los campos


especificados.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT DISTINCT x.company, y.order_date, y.shipped_on ;
FROM customer x, orders y ;
WHERE x.cust_id = y.cust_id

Ejemplo 4

El ejemplo 4 muestra los campos country, postalcode y company en orden


ascendente.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT country, postalcode, company ;
FROM customer ;
ORDER BY country, postalcode, company

Ejemplo 5

El ejemplo 5 almacena el contenido de los campos de dos tablas en una


tercera tabla.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT x.company, y.order_date, y.shipped_on ;

122
FROM customer x, orders y ;
WHERE x.cust_id = y.cust_id ;
INTO TABLE custship.dbf
BROWSE

Ejemplo 6

El ejemplo 6 muestra únicamente los registros con una fecha de pedido anterior
al 16/02/1994.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT x.company, y.order_date, y.shipped_on ;
FROM customer x, orders y ;
WHERE x.cust_id = y.cust_id ;
AND y.order_date < {^1994-02-16}

Ejemplo 7

El ejemplo 7 muestra todos los clientes, pero sólo las órdenes con una fecha
anterior a 02/16/1994.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT x.company, y.order_date, y.shipped_on ;
FROM customer x ;
LEFT JOIN orders y ;
ON x.cust_id = y.cust_id ;
AND y.order_date < {^1994-02-16}

Ejemplo 8

El ejemplo 8 muestra los nombres de todas la compañías de customer con un


código postal que coincide con el de la tabla orders.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT company FROM customer x WHERE ;
EXISTS (SELECT * FROM orders y WHERE x.postalcode = y.postalcode)

Ejemplo 9

El ejemplo 9 muestra todos los registros de customer que tengan un nombre de


país que comience por U mayúscula seguido de un carácter desconocido.

123
CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT * FROM customer x WHERE x.country LIKE "U_"

Ejemplo 10

El ejemplo 10 muestra todos los registros de customer que tienen un nombre


de país que empieza con una letra mayúscula U seguida por un carácter
desconocido.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT * FROM customer x WHERE x.country LIKE "U_"

Ejemplo 11

El ejemplo 11 muestra los nombres de todas las ciudades en customer en


mayúsculas y el resultado se envía a la columna CityList.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT UPPER(city) AS CityList FROM customer

Ejemplo 12

En el ejemplo 12 se muestra cómo se puede realizar una consulta de datos que


contenga signos de porcentaje (%). Se coloca una barra inversa (\) antes del
signo de porcentaje para indicar que debe ser tratado como un literal, y se
especifica la barra inversa como el carácter de escape en la cláusula ESCAPE.

Dado que las tablas de ejemplo incluidas con Visual FoxPro no contienen el
carácter de porcentaje, esta consulta no devolverá ningún resultado.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT * FROM customer;
WHERE company LIKE "%\_%" ESCAPE "\"

Ejemplo 13

En el ejemplo 13 se muestra cómo se puede realizar una consulta de datos que


contenga signos de subrayado (%). Se coloca una barra inversa (\) antes del
signo de subrayado para indicar que debe ser tratado como un literal, y se
especifica la barra inversa como el carácter de escape en la cláusula ESCAPE.

124
Dado que las tablas de ejemplo incluidas con Visual FoxPro no contienen el
carácter de subrayado, esta consulta no devolverá ningún resultado.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT * FROM customer;
WHERE company LIKE "%\_%" ESCAPE "\"

Ejemplo 14

En el ejemplo 14, el carácter Escape se utiliza como un literal. El guión es tanto


el carácter escape como un literal. La consulta devuelve todas las filas en las
que el nombre de la organización contiene un signo de porcentaje seguido de
un guión.

Dado que las tablas de ejemplo incluidas con Visual FoxPro no contienen el
carácter de signo de porcentaje, esta consulta no devolverá ningún resultado.

CLOSE ALL
CLOSE DATABASES
OPEN DATABASE (HOME(2) + 'data\testdata')
SELECT * FROM customer;
WHERE company LIKE "%-%--%" Escape "-"

125

Potrebbero piacerti anche