Sei sulla pagina 1di 148

CLARION + SQL

Manual de Aplicaciones Clarion + SQL


El origen del manual, es una compilacion de cursos dictados por Fernando Cerini / Gustavo Olmedo entre
otros en el mundo Clarion Hispano.
info@templatesClarion.com.ar
olmedog@gmail.com

Contents

Tabla de Contenido
0

Part I Programando con CLARION + SQL (MS-SQL)

1 Nociones Basicas
................................................................................................................................... 8
2 Microsoft SQL
...................................................................................................................................
Server
10
Service Manager
..........................................................................................................................................................
Administrador..........................................................................................................................................................
Coorporativo
DTS - Importacin
..........................................................................................................................................................
y exportacin de datos
Gestin de Tablas
..........................................................................................................................................................

10
12
13
14

3 Introduccion...................................................................................................................................
al lenguaje SQL - MSQL-Server
16
Normalizacin..........................................................................................................................................................
de la base de Datos
Primera Forma
.........................................................................................................................................................
Normal
Segunda .........................................................................................................................................................
Forma Normal
Tercera Forma
.........................................................................................................................................................
Normal
Ejemplo de
.........................................................................................................................................................
Normalizacion
Integridad de ..........................................................................................................................................................
los datos
Tipos datos MSSQL
..........................................................................................................................................................
Campos Identity
.........................................................................................................................................................
Lenguaje de Definicin
..........................................................................................................................................................
de datos (LDD)
CREATE .........................................................................................................................................................
ALTER .........................................................................................................................................................
DROP .........................................................................................................................................................
TRUNCATE
.........................................................................................................................................................
Lenguaje de Manipulacin
..........................................................................................................................................................
de Datos Nivel Bsico
Recuperar.........................................................................................................................................................
Datos con SELECT
FROM
.........................................................................................................................................
WHERE y HAVING:
.........................................................................................................................................
Filtrar filas
ORDER BY
.........................................................................................................................................
JOIN: Combinaciones
.........................................................................................................................................
Utilizar alias de tablas
.........................................................................................................................................
DISTINCT
.........................................................................................................................................
TOP n
.........................................................................................................................................
Agregar filas
.........................................................................................................................................................
con INSERT
Cambiar datos
.........................................................................................................................................................
con UPDATE
Eliminar filas
.........................................................................................................................................................
con DELETE
Trabajando con
..........................................................................................................................................................
fechas
Elementos de..........................................................................................................................................................
sintaxis de Transact-SQL
Consultas: Nivel
..........................................................................................................................................................
avanzado
Usar funciones
.........................................................................................................................................................
de agregado en la lista de seleccin
Agrupar filas
.........................................................................................................................................................
con GROUP BY
Combinar.........................................................................................................................................................
resultados con UNION
Subconsultas..........................................................................................................................................................
Subconsultas
.........................................................................................................................................................
con Alias
Subconsultas
.........................................................................................................................................................
con IN
Subconsultas
.........................................................................................................................................................
con NOT IN
Subconsultas
.........................................................................................................................................................
en UPDATE, DELETE e INSERT
Subconsultas
.........................................................................................................................................................
con operadores de comparacin
Subconsultas
.........................................................................................................................................................
con EXISTS

16
19
19
19
20
24
26
28
30
30
30
30
31
31
31
33
34
36
36
44
45
45
45
47
49
51
53
58
58
60
63
64
66
67
69
69
70
72

www.templatesclarion.com.ar
3

Curso SQL + Clarion - www.templatesclarion.com.ar


Subconsultas
.........................................................................................................................................................
con NOT EXISTS
Subconsultas
.........................................................................................................................................................
usadas en lugar de una expresin
Mltiples .........................................................................................................................................................
niveles de anidamiento
Procesamiento
.........................................................................................................................................................
condicional con CASE
Transacciones
..........................................................................................................................................................
y control de la concurrencia
Bloqueos .........................................................................................................................................................
Read Uncommited
.........................................................................................................................................................
Read Commited
.........................................................................................................................................................
Repeatable
.........................................................................................................................................................
Read
Serializable
.........................................................................................................................................................

74
75
75
76
77
79
80
81
82
83

4 Diccionario ...................................................................................................................................
de Datos (DCT)
84
Propiedades de
..........................................................................................................................................................
Archivos
Tipos de Datos
..........................................................................................................................................................
Clarion / MS-SQL
Usando SQLIdentity
..........................................................................................................................................................
en Clarion 6
Claves/Indices
..........................................................................................................................................................
(Keys)
Integridad referencial
..........................................................................................................................................................
- Relaciones
Creacion Tablas
..........................................................................................................................................................
en Motor
Utility Template
.........................................................................................................................................................
Synchronizer
.........................................................................................................................................................
File Import
.........................................................................................................................................................
Conexion a una
..........................................................................................................................................................
Base de Datos
Driver Nativo
.........................................................................................................................................................
- SQL Accelerator Drivers
ODBC - .........................................................................................................................................................
Open DataBase Conectivity
Convertir TPS
..........................................................................................................................................................
a SQL
"CSTRING"
.........................................................................................................................................................
por "STRING"
Manejo de
.........................................................................................................................................................
Fechas
Migrar Datos
.........................................................................................................................................................
Existentes

85
87
90
91
92
93
93
94
97
100
101
102
102
104
104
105

5 Usando SQL
...................................................................................................................................
en Aplicaciones (APP)
105
Recomendaciones
..........................................................................................................................................................
Ventana de Login
..........................................................................................................................................................
Automtico
Validacion de
..........................................................................................................................................................
Datos
SQL Embebido
..........................................................................................................................................................
en Clarion
Prop:SQL ..........................................................................................................................................................
Comando BUFFER
..........................................................................................................................................................
Prop:SQLFilter
..........................................................................................................................................................
Prop:WHERE
..........................................................................................................................................................
SetFilter con..........................................................................................................................................................
codigo SQL
Filtrando Campos
..........................................................................................................................................................
DATE
StupidTempTable
..........................................................................................................................................................
Codigo Clarion
..........................................................................................................................................................
Vs. SQL
Manejo de Errores
..........................................................................................................................................................
Manejo Set, Next,
..........................................................................................................................................................
Previous
Clarion y NULLs
..........................................................................................................................................................
SQL / VIEWs..........................................................................................................................................................
Browses
..........................................................................................................................................................
SQL Advanced
..........................................................................................................................................................
Tab
Process /Reports
..........................................................................................................................................................
Transacciones
..........................................................................................................................................................
Batch
Manejo de Transacciones
..........................................................................................................................................................
Stored Procedures
..........................................................................................................................................................
Usando TurboSQL
..........................................................................................................................................................
Uso del trace..........................................................................................................................................................
Cargas de Cabecera
..........................................................................................................................................................
- Detalle

www.templatesclarion.com.ar

106
108
108
109
109
111
111
112
113
113
114
116
117
117
118
119
120
122
125
126
126
127
128
128
131

Contents

Creando un ..........................................................................................................................................................
Editor de SQL

132

6 Links - Material
...................................................................................................................................
Recomendado
141
In-Memory Database
..........................................................................................................................................................
Driver
Ejemplos ..........................................................................................................................................................

Indice

143
143

147

www.templatesclarion.com.ar
5

Parte

I
www.templatesclarion.com.ar

Curso SQL + Clarion - www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

Clarion + SQL

Microsoft SQL Server


Introduccion al lenguaje SQL - MSQL-Server
Diccionario de Datos (DCT)
Usando SQL en Aplicaciones (APP)
Links - Material Recomendado

1.1

Nociones Basicas
Aplicaciones Cliente/Servidor y Base de datos Relacional
Un trmino utilizado con frecuencia en el uso de la base de datos es cliente/servidor.
Si Ud. esta usando archivos planos (ej. TPS), ya sea en un servidor o una computadora
local, significa que "NO" esta usando cliente/servidor. En el entorno Cliente/servidor,
ambas partes poseen cierta inteligencia. Las bases de datos Relacionadas son un ejemplo
comn del proceso del cliente/del servidor.
El Servidor de Bases de datos proporciona destacables ventajas sobre los archivos
planos; velocidad, integridad de datos, compatibilidad con otros con productos, facilidad
de administracin, etc.

Base de Datos SQL


La mayora de las aplicaciones Cliente/Servidor actan como front-ends (interfaces)
corriendo en una estacin de trabajo Cliente y solicitando servicios de datos de un motor
de base de datos (Como Oracle, Informix, SyBase, MS-SQL) corriendo en un servidor. La
mayora de estas bases de datos son accedidas utilizando el Lenguaje de Query Consulta
Estructurado (Structured Query Languaje o SQL).
SQL fue originalmente desarrollado como un lenguaje de consultas para permitir a los
usuarios extraer informacin de una Base de Datos. A lo largo de los aos, el SQL fue
extendido para permitir programacin adems del acceso a los datos.
SQL se ha convertido en la herramienta estndar de consulta usada para acceder a los
motores de bases de datos. Programas SQL son los frecuentemente mas utilizados para
el ncleo transaccional de una base de datos. Sin embargo, el SQL no es un lenguaje

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

completo ya que carece de diseo de interfaces, por ende el SQL es embebido dentro
de un lenguaje con mayor capacidad y generalidad ( como Clarion / C++ ) para crear
aplicaciones completas.
Los sistemas de gestin de base de datos con soporte SQL ms utilizados son, por orden
alfabtico:

DB2

Firebird

Informix

Interbase

MySQL

Oracle

PostgreSQL

SQL Server

Sybase ASE

SQL (Structured Query Language)


El Lenguaje de Consulta Estructurado (SQL) es el Lenguaje para acceder a una base de
datos relacional; el mismo fue adoptado como estndar de la industria en 1986.
El SQL es un lenguaje de acceso a bases de datos que explota la flexibilidad y potencia
de los sistemas relacionales permitiendo gran variedad de operaciones sobre los mismos.

Clarion y SQL
La tecnologa de los File Drivers de Clarion permite escribir aplicaciones que accedan a
bases de datos SQL sin necesidad de escribir ni sola una lnea de cdigo SQL. El File
Driver de Clarion es el que se comunica con la base de datos generando
automticamente la sentencia SQL que el motor de base de datos requiere a partir de las
instrucciones estndares de I/O del lenguaje Clarion. Como estos Drivers SQL estn
especficamente diseados para conversar con cada base de datos en particular
(excepto el ODBC Driver, que por supuesto, es una versin genrica de SQL), el cdigo
SQL generado est optimizado para utilizar la sintaxis especifica de ese motor. Esto
significa que los usuario Clarion no estn obligados a aprender (utilizar SQL) para escribir
aplicaciones Cliente/Servidor.
El hecho de que un programador Clarion no este obligado a escribir SQL no limita de
ninguna manera la capacidad de Clarion para generar programas Cliente/Servidor. Ud.
puede embeber su propia sentencia SQL para extender lo que el File Driver hace por
usted, o puede tomar el control total sobre la base de datos para realizar cualquier tarea
que necesite realizar.
Existen varias maneras para embeber sentencias propias de SQL en un programa Clarion,
si lo desea. Esto le brinda, al programador Clarion, la flexibilidad de permitir que el File
Driver lo haga, o directamente indicar como lo debe hacer.

www.templatesclarion.com.ar

10

Curso SQL + Clarion - www.templatesclarion.com.ar

Lenguaje de Definicin de datos (DDL)


El lenguaje de Definicin de datos (Data Definition Language (DDL)), es el que se
encarga de la modificacin de la estructura de los objetos de la base de datos. (mas
detalle ver Lenguaje de Definicin de datos (LDD) )

Lenguaje de Manipulacin de Datos (DML)


El Lenguaje de Manipulacin de Datos (Data Manipulation Language (DML)), es un
lenguaje que nos permite a los usuarios llevar a cabo las tareas de consulta o
manipulacin de los datos, organizados por el modelo de datos adecuado. Mediante el
uso del SQL se recuperaran y manipularan datos en una base de datos relacional. (mas
detalle ver Lenguaje de Manipulacin de Datos )

1.2

Microsoft SQL Server

1.2.1

Service Manager
Enterprise Manager
Query Analizer
Data Transformation Services (DTS)

Service Manager
SQL Server instala varios servicios en nuestra maquina , el nombre del servicio se
puede ver/manejar desde el administrador de servicios de windows: Inicio ->
Programas -> Herramientas Administrativas -> Servicios, desde donde se puede parar,
arracar y cambiar el usuario que los ejecuta.
Tambin podemos utilizar una utilidad que instala SQL Server El Administrador de
Servicios de SQL Server, este programa se encuentra en la barra de tareas de windows

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

11

SQL Server: Es el servicio principal y arranca el SQL Server. Se llama MSSQLSERVER y


si hay varias instancias en una misma mquina, el servicio se llama
MSSQL$Nombre_de_instancia.
SQL Server Agent: Es el Agente de SQL Server. Se utiliza para la programacin de
tareas, alertas, mail y se llama SQLSERVERAGENT. Similar al anterior si hay multiples
instancias el servicio se llama SQLAGENT$Nombre_de_instancia.
Coordinador de transacciones distribuidas : DTC, utilizado para tareas entre varios
servidores distribuidos. Se llama Distributed Transaction Coordinator.
Microsoft Seach: Utilizado para la bsqueda de texto completo en las bases de datos e
indices de texto, este servicio solo estar si se ha instalado esta utilidad. Se llama
Microsoft Search.
Asistente del Active Directory.

www.templatesclarion.com.ar

12

1.2.2

Curso SQL + Clarion - www.templatesclarion.com.ar

Administrador Coorporativo
Esta herramienta es la base de trabajo del SQL Server 2000. A travs de el podemos
realizar cualquier tarea relacionada con SQL Server, adems podemos administrar no
solo nuestro SQL Server sino tambin servidores SQL Server remotos distribuidos en
otras mquinas. El administrador corporativo pertenece a la MMC (Microsoft Management
Console) y como tal se puede aadir a las consolas ya existentes.
Para ejecutar el administrador corporativo debemos ir a inicio -> programas -> Microsoft
SQL Server -> administrador corporativo, una vez ejecutado nos aparece la imagen que
visualizamos abajo, a la izquierda nos muestra los datos estructurados en forma de rbol
y a la derecha diversas opciones dependiendo de donde estemos navegando por el rbol.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

1.2.3

13

DTS - Importacin y exportacin de datos


Una de las herramientas incorporadas en SQL Server 2000 es el servicios de
transformacin de datos (DTS Data Transformation Services). Incluye herramientas y
objetos que permiten mover datos entre varios orgenes de datos diferentes o iguales.
Que es el DTS?
Es una herramienta para mover, copiar, modificar y trabajar con orgenes de datos
iguales o diferentes. En este punto vamos a ver la importacin y exportacin de datos
entre dos orgenes de datos .
DTS tiene una arquitectura OLE DB por lo que puede copiar y transformar mltiples or
genes de datos, entre ellos:
-

SQL Server
Oracle
Access, excel, Outlook, archivos de texto
Exchange Server
Orgenes de datos proporcionados por terceros

Para ejecutar el asistente de importacin/exportacin podemos hacerlo de varias formas.

www.templatesclarion.com.ar

14

Curso SQL + Clarion - www.templatesclarion.com.ar

Una es desde la consola (cmd) del sistema ejecutando el archivo dtswiz. Otra opcin es ir
desde el men Inicio -> programas -> Microsoft SQL Server -> Importacin y exportaci
n de datos y la ultima, por supuesto, desde el administrador corporativo. Se puede
ejecutar posicionndonos en una base de datos y con el botn derechos seleccionamos
Todas las tareas -> importar datos o exportar datos dependiendo de la tarea que vamos
a realizar.

1.2.4

Gestin de Tablas
Para crear tablas SQL Server proporciona varias formas, podemos crear tablas desde el
administrador corporativo, o a travs de transact-sql con el comando Create Table . Del
mismo modo que las creamos las podemos modificar, borrar, renombralas, copiarlas, etc.
Las tablas deben tener un nombre como mximo de 128 caracteres y el nombre debe
empezar por un carcter alfabtico, a excepcin de las tablas temporales que se crean
con el signo # delante del nombre, para la sesin del usuario actual y con dos ## para
las tablas temporales globales, accesibles a todos los usuarios.
Para crear una tabla desde el administrador corporativo seleccionamos una base de datos
y dentro de estas el nodo tablas, pulsamos con el botn derecho del ratn y
seleccionamos Nueva tabla:

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

15

Modificar y/o borrar una tabla: Para realizar estas acciones tenemos que posicionar el rat
n sobre la tabla que queremos borrar o modificar y pulsando con el botn derecho
seleccionamos la opcin deseada.
Las instrucciones de Transact-SQL / Querys para manipular tablas se ejecutan desde el
Analizador de Consultas seleccionando la base de datos que se quiere manipular. Para
ejecutar el Analizador de Consultas debemos ir a inicio -> programas -> Microsoft SQL
Server -> Analizador de Consultas. O tambien desde el Administrador Coorporativo en el
menu Herramientas -> Analizador de Consultas.

www.templatesclarion.com.ar

16

1.3

Curso SQL + Clarion - www.templatesclarion.com.ar

Introduccion al lenguaje SQL - MSQL-Server


Normalizacin de la base de Datos
Integridad de los datos
Tipos datos MSSQL
Lenguaje de Definicin de datos (LDD)
Lenguaje de Manipulacin de Datos Nivel Bsico
Trabajando con fechas
Elementos de sintaxis de Transact-SQL
Consultas: Nivel avanzado
Subconsultas
Transacciones y control de la concurrencia

1.3.1

Normalizacin de la base de Datos


Qu es la normalizacin?
La normalizacin es el proceso mediante el cual se transforman datos complejos a un
conjunto de estructuras de datos ms pequeas, que adems de ser ms simples y ms
estables, son ms fciles de mantener. Tambin se puede entender la normalizacin

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

17

como una serie de reglas que sirven para ayudar a los diseadores de bases de datos a
desarrollar un esquema que minimice los problemas al momento de actualizar y
consultar los datos. Cada regla est basada en la que le antecede.

Por que normalizar?


La normalizacin se adopt porque el viejo estilo de poner todos los datos en un solo
lugar, como un archivo o una tabla de la base de datos, era ineficiente y conduca a
errores de lgica cuando se trataban de manipular los datos.
La normalizacin tambin hace las cosas fciles de entender. Los seres humanos
tenemos la tendencia de simplificar las cosas al mximo. Lo hacemos con casi todo,
desde los animales hasta con los automviles. Vemos una imagen de gran tamao y la
hacemos ms simple agrupando cosas similares juntas.
Las guas que la normalizacin provee crean el marco de referencia para simplificar una
estructura de datos compleja.
Otra ventaja de la normalizacin de base de datos es el consumo de espacio. Una base
de datos normalizada ocupa menos espacio en disco que una no normalizada. Hay menos
repeticin de datos, lo que tiene como consecuencia un mucho menor uso de espacio en
disco.
El proceso de normalizacin tiene un nombre y una serie de reglas para cada fase. Esto
puede parecer un poco confuso al principio, pero poco a poco se va entendiendo el
proceso, as como las razones para hacerlo de esta manera.

Grados de normalizacin
Existen bsicamente tres niveles de normalizacin
Primera Forma Normal (1NF)
Segunda Forma Normal (2NF)
Tercera Forma Normal (3NF)
Cada una de estas formas tiene sus propias reglas.
Cuando una base de datos se conforma a un nivel, se considera normalizada a esa forma
de normalizacin.
(No siempre es una buena idea tener una base de datos conformada en el nivel ms alto
de normalizacin, puede llevar a un nivel de complejidad que pudiera ser evitado si
estuviera en un nivel ms bajo de normalizacin).

Resumen
En la tabla siguiente se describe brevemente en que consiste cada una de las reglas, y
posteriormente se explican con ms detalle.
Primera Forma Normal(1FN): Incluye la eliminacin de todos los grupos repetidos.
Segunda Forma Normal (2FN): Asegura que todas las columnas que no son llave
sean completamente dependientes de la llave primaria (PK).
Tercera Forma Normal (3FN): Elimina cualquier dependencia transitiva. Una
dependencia transitiva es aquella en la cual las columnas que no son llave son
dependientes de otras columnas que tampoco son llave.

www.templatesclarion.com.ar

18

Curso SQL + Clarion - www.templatesclarion.com.ar

Ejemplo de Normalizacion
Qu tan lejos debe llevar la normalizacin?
En ultima instancia, depende de nosotros.
La siguiente decisin es qu tan lejos debe llevar la normalizacin?
La normalizacin es una ciencia subjetiva. Determinar las necesidades de simplificacin
depende de nosotros.
Si nuestra base de datos va a proveer informacin a un solo usuario para un propsito
simple y existen pocas posibilidades de expansin, normalizar los datos hasta la 3FN
quiz sea algo exagerado.
Las reglas de normalizacin existen como guas para crear tablas que sean fciles de
manejar, as como flexibles y eficientes. A veces puede ocurrir que normalizar los datos
hasta el nivel ms alto no tenga sentido.

La pregunta fundamental
Se estn dividiendo tablas slo para seguir las reglas o estas divisiones son en verdad
prcticas?.
stas son el tipo de cosas que nosotros como diseadores de la base de datos,
necesitamos decidir, y la experiencia y el sentido comn nos pueden auxiliar para tomar
la decisin correcta. La normalizacin no es una ciencia exacta, ms bien subjetiva.

Existen seis niveles ms de normalizacin!


Los cuales no se han discutido aqu porque no tienen gran aplicacin en casos practicos
Ellos son:
Forma Normal Boyce-Codd
Cuarta Forma Normal (4NF)
Quinta Forma Normal (5NF) o Forma Normal de Proyeccin-Unin
Forma Normal de Proyeccin-Unin Fuerte
Forma Normal de Proyeccin-Unin Extra Fuerte
Forma Normal de Clave de Dominio
Estas formas de normalizacin pueden llevar las cosas ms all de lo que necesitamos.
Existen para cerrar conceptualmente dentro de la teoria Relacional (para hacer una base
de datos realmente relacional). Tienen que ver principalmente con dependencias
mltiples y claves relacionales.

En resumen
La normalizacin es una tcnica que se utiliza para crear relaciones lgicas apropiadas
entre tablas de una base de datos.
Ayuda a prevenir errores lgicos en la manipulacin de datos. La normalizacin facilita
tambin agregar nuevas columnas sin romper el esquema actual ni las relaciones.
www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

19

Existen varios niveles de normalizacin: Primera Forma Normal, Segunda Forma Normal,
Tercera Forma Normal, Forma Normal Boyce-Codd, Cuarta Forma Normal, Quinta Forma
Normal o Forma Normal de Proyeccin-Unin, Forma Normal de Proyeccin-Unin Fuerte,
Forma Normal de Proyeccin-Unin Extra Fuerte y Forma Normal de Clave de Dominio.
Cada nuevo nivel o forma nos acerca ms a hacer una base de datos verdaderamente
relacional.
Se discutieron las primeras tres formas. stas proveen suficiente nivel de normalizacin
para cumplir con las necesidades de la mayora de las bases de datos.
Normalizar demasiado puede conducir a tener una base de datos ineficiente y
hacer a su esquema demasiado complejo para trabajar. Un balance apropiado de
sentido comn y prctico puede ayudarnos a decidir cundo normalizar.
1.3.1.1

Primera Forma Normal


La regla de la Primera Forma Normal establece que las columnas repetidas deben
eliminarse y colocarse en tablas separadas.

Ventajas
Poner la base de datos en la Primera Forma Normal resuelve el problema de los
encabezados de columna mltiples.
Muy a menudo, los diseadores de bases de datos inexpertos harn algo similar a la
tabla no normalizada. Una y otra vez, crearn columnas que representen los mismos
datos. La normalizacin ayuda a clarificar la base de datos y a organizarla en partes ms
pequeas y ms fciles de entender. En lugar de tener que entender una tabla
gigantesca y monoltica que tiene muchos diferentes aspectos, slo tenemos que
entender los objetos pequeos y ms tangibles, as como las relaciones que guardan con
otros objetos tambin pequeos.
1.3.1.2

Segunda Forma Normal


La regla de la Segunda Forma Normal establece que todas las dependencias parciales se
deben eliminar y separar dentro de sus propias tablas. Una dependencia parcial es un
trmino que describe a aquellos datos que no dependen de la llave primaria de la tabla
para identificarlos.

Ventajas
Una vez alcanzado el nivel de la Segunda Forma Normal, se controlan la mayora de los
problemas de lgica. Podemos insertar un registro sin un exceso de datos en la mayora
de las tablas.
1.3.1.3

Tercera Forma Normal


Una tabla est normalizada en esta forma si todas las columnas que no son llave son
funcionalmente dependientes por completo de la llave primaria y no hay dependencias
transitivas. Comentamos anteriormente que una dependencia transitiva es aquella en la
cual existen columnas que no son llave que dependen de otras columnas que tampoco
son llave.

www.templatesclarion.com.ar

20

Curso SQL + Clarion - www.templatesclarion.com.ar

Ventajas
Cuando las tablas estn en la Tercera Forma Normal se previenen errores de lgica
cuando se insertan o borran registros. Cada columna en una tabla est identificada de
manera nica por la llave primaria, y no deben haber datos repetidos. Esto provee un
esquema limpio y elegante, que es fcil de trabajar y expandir.
1.3.1.4

Ejemplo de Normalizacion
Un dato sin normalizar no cumple con ninguna regla de normalizacin. Para explicar con
un ejemplo en que consiste cada una de las reglas, vamos a considerar los datos de la
siguiente tabla.
ID
ORDEN

FECHA

2301

ID
CLI

NOM
CLIENTE

ESTADO

NUM
ITEM

DESC
ITEM

CANT

PRECIO

2/23/03 101

MARTI

CA

3786

RED

35

2301

2/23/03 101

MARTI

CA

4011

RAQUETA 6

65

2301

2/23/03 101

MARTI

CA

9132

PAQ-3

4.75

2302

2/25/03 107

HERMAN

WI

5794

PAQ-6

5.0

2303

2/27/03 110

WESPORTS MI

4011

RAQUETA 2

65

2303

2/27/03 110

WESPORTS MI

3141

FUNDA

10

Al examinar estos registros, podemos darnos cuenta que contienen un grupo repetido
para NUM_ITEM, DESC_ITEM, CANT y PRECIO. La 1FN prohibe los grupos repetidos, por
lo tanto tenemos que convertir a la primera forma normal.
Los pasos a seguir son:
Tenemos que eliminar los grupos repetidos.
Tenemos que crear una nueva tabla con la PK de la tabla base y el grupo repetido.
Los registros quedan ahora conformados en dos tablas que llamaemos ORDENES y
ARTICULOS_ORDENES
- ORDENES
ID_ORDE
N

FECHA

ID_CLIENT NOM_CLIENT ESTADO


E
E

2301

2/23/03

101

MARTI

CA

2302

2/25/03

107

HERMAN

WI

2303

2/27/03

110

WE-SPORTS

MI

- ARTICULOS_ORDENES
ID_ORDEN NUM_ITEM DESC_ITEM CANT

PRECIO

2301

3786

RED

35

2301

4011

RAQUETA

65

2301

9132

PAQ-3

4.75

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

2302

5794

PAQ-6

5.0

2303

4011

RAQUETA

65

2303

3141

FUNDA

10

www.templatesclarion.com.ar

21

22

Curso SQL + Clarion - www.templatesclarion.com.ar

Ahora procederemos a aplicar la segunda formal normal, es decir, tenemos que


eliminar cualquier columna no llave que no dependa de la llave primaria de la tabla.
Los pasos a seguir son:
Determinar cules columnas que no son llave no dependen de la llave primaria de la
tabla.
Eliminar esas columnas de la tabla base.
Crear una segunda tabla con esas columnas y la(s) columna(s) de la PK de la cual
dependen.
La tabla ORDENES ya est en 2FN. Cualquier valor nico de ID_ORDEN determina un
slo valor para cada columna. Por lo tanto, todas las columnas son dependientes de la
llave primaria ID_ORDEN.
Por su parte, la tabla ARTICULOS_ORDENES no se encuentra en 2FN ya que las columnas
PRECIO y DESC_ITEM son dependientes de NUM_ITEM, pero no son dependientes de
ID_ORDEN.
Lo que haremos a continuacin es eliminar estas columnas de la tabla
ARTICULOS_ORDENES y crear una tabla ARTICULOS con dichas columnas y la llave
primaria de la que dependen.
Las tablas quedan ahora de la siguiente manera.
- ARTICULOS_ORDENES
ID_ORDEN

NUM_ITEM

CANT

2301

3786

2301

4011

2301

9132

2302

5794

2303

4011

2303

3141

NUM_ITEM

DESC_ITEM

PRECIO

3786

RED

35

4011

RAQUETA

65

9132

PAQ-3

4.75

5794

PAQ-6

5.0

4011

RAQUETA

65

3141

FUNDA

10

- ARTICULOS

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

23

La tercera forma normal nos dice que tenemos que eliminar cualquier columna no llave
que sea dependiente de otra columna no llave.
Los pasos a seguir son:
Determinar las columnas que son dependientes de otra columna no llave.
Eliminar esas columnas de la tabla base.
Crear una segunda tabla con esas columnas y con la columna no llave de la cual son
dependientes.
Al observar las tablas que hemos creado, nos damos cuenta que tanto la tabla
ARTICULOS, como la tabla ARTICULOS_ORDENES se encuentran en 3FN. Sin embargo la
tabla ORDENES no lo est, ya que NOM_CLIENTE y ESTADO son dependientes de
ID_CLIENTE, y esta columna no es la llave primaria.
Para normalizar esta tabla, moveremos las columnas no llave y la columna llave de la
cual dependen dentro de una nueva tabla CLIENTES. Las nuevas tablas CLIENTES y
ORDENES se muestran a continuacin.
- ORDENES
ID_ORDEN

FECHA

ID_CLIENTE

2301

2/23/03

101

2302

2/25/03

107

2303

2/27/03

110

- CLIENTES
ID_CLIENTE

NOM_CLIENTE

ESTADO

101

MARTI

CA

107

HERMAN

WI

110

WE-SPORTS

MI

www.templatesclarion.com.ar

24

1.3.2

Curso SQL + Clarion - www.templatesclarion.com.ar

Integridad de los datos


La integridad de los datos garantiza la calidad de los datos de la base de datos.
Por ejemplo, si se especifica para un empleado el valor de employee_id (identificador del
empleado) 123, la base de datos no debe permitir que ningn otro empleado tenga el
mismo valor de identificador. Si tiene una columna employee_rating para la que se
prevea valores entre el 1 y el 5, la base de datos no debe aceptar el valor 6. Si en la
tabla hay una columna dept_id en la que se almacene el nmero de departamento del
empleado, la base de datos slo debe permitir valores que correspondan a los nmeros
de departamento de la compaa.
Dos pasos importantes en el diseo de las tablas son la identificacin de valores vlidos
para una columna y la determinacin de cmo forzar la integridad de los datos en la
columna.

Tipos de Integridad
Estas son las categoras de integridad de datos:

Integridad
Integridad
Integridad
Integridad

de entidad
de dominio
referencial
definida por el usuario

Integridad de entidad
La integridad de entidad define una fila como entidad nica para una tabla determinada.
La integridad de entidad fuerza la integridad de la columna o columnas de los
identificadores o la clave principal de una tabla (mediante ndices, restricciones UNIQUE,
restricciones PRIMARY KEY o propiedades IDENTITY).

Integridad de dominio
La integridad de dominio viene dada por la validez de las entradas para una columna
determinada. Puede forzar la integridad de dominio si restringe el tipo (mediante tipos de
datos), el formato (mediante las reglas y las restricciones CHECK), o el intervalo de
valores posibles (mediante restricciones FOREIGN KEY, restricciones CHECK, definiciones
DEFAULT, definiciones NOT NULL y reglas).

Integridad referencial
La integridad referencial protege las relaciones definidas entre las tablas cuando se crean
o se eliminan registros. En SQL Server la integridad referencial se basa en las relaciones
entre claves externas y claves principales o entre claves externas y claves exclusivas
(mediante restricciones FOREIGN KEY, restricciones CHECK). La integridad referencial
garantiza que los valores clave sean coherentes en las distintas tablas. Para conseguir
esa coherencia, es preciso que no haya referencias a valores inexistentes y que, si
cambia el valor de una clave, todas las referencias a ella se cambien en consecuencia en
toda la base de datos.
Cuando se fuerza la integridad referencial, SQL Server impide a los usuarios:

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

25

Agregar registros a una tabla relacionada si no hay ningn registro asociado en la tabla
principal.
Cambiar valores en una tabla principal de manera que queden registros hurfanos en
una tabla relacionada.
Eliminar registros de una tabla principal cuando hay registros relacionados
coincidentes.
Por ejemplo, con las tablas sales (compras) y titles (ttulos) de la base de datos pubs, la
integridad referencial se basa en la relacin entre la clave externa (title_id) de la tabla
sales y la clave principal (title_id) de la tabla titles.

Integridad definida por el usuario


La integridad definida por el usuario le permite definir reglas de la compaa especficas
que no pertenecen a ninguna otra categora de integridad. Todas las categoras de
integridad son compatibles con la integridad definida por el usuario (todas las
restricciones en columnas y tablas de CREATE TABLE, procedimientos almacenados y
desencadenadores).

www.templatesclarion.com.ar

26

1.3.3

Curso SQL + Clarion - www.templatesclarion.com.ar

Tipos datos MSSQL


Tipos de datos numricos.
SQL Server dispone de varios tipos de datos nmericos. Cuanto mayor sea el nmero
que puedan almacenar mayor ser en consecuencia el espacio utilizado para
almacenarlo. Como regla general se recomienda usar el tipo de dato mnimo posible.
Todos los dato numricos admiten el valor NULL.
Bit. Una columna o variable de tipo bit puede almacenar el rango de valores de 1 a 0.
Tinyint. Una columna o variable de tipo tinyint puede almacenar el rango de valores
de 0 a 255.
SmallInt. Una columna o variable de tipo smallint puede almacenar el rango de
valores -32768 a 32767.
Int. Una columna o variable de tipo int puede almacenar el rango de valores -231 a
231-1 .
BigInt. Una columna o variable de tipo bigint puede almacenar el rango de valores
-263 a 263-1 .
Decimal(p,s). Una columna de tipo decimal puede almacenar datos nmericos
decimales sin redondear. Donde p es la precision (nmero total del dgitos) y s la
escala (nmero de valores decimales)
Float. Una columna de datos float puede almacenar el rango de valores
-1,79x-10308 a 1,79x-10308, , si la definimos con el valor mxmo de precisin. La
precisin puede variar entre 1 y 53.
Real. Sinnimo de float(24). Puede almacenar el rango de valores -3,4x-1038 a
3,4x-1038,
Money. Almacena valores nmericos monetarios de -263 a 263-1, con una precisin
de hasta diexz milesimas de la unidad monetaria.
SmallMoney. Almacena valores nmericos monetarios de -214.748,3647 a
214.748,3647, con una precisin de hasta diez milesimas de la unidad monetaria.
Todos los tipos de datos enteros pueden marcarse con la propiedad identity para
hacerlos autonumricos.

Tipos de datos de caracter.


Char(n). Almacena n caracteres en formato ASCII, un byte por cada letra. Cuando
almacenamos datos en el tipo char, siempre se utilizan los n caracteres indicados,
incluso si la entrada de datos es inferior. Por ejemplo, si en un char(5), guardamos el
valor 'A', se almacena 'A ', ocupando los cinco bytes.
Varchar(n).Almacena n caracteres en formato ASCII, un byte por cada letra. Cuando
almacenamos datos en el tipo varchar, unicamente se utilizan los caracteres
necesarios,Por ejemplo, si en un varchar(255), guardamos el valor 'A', se almacena

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

27

'A', ocupando solo un byte bytes.


Varchar(max). Igual que varchar, pero al declararse como max puede almacenar
-1 bytes.

231

Nchar(n).Almacena n caracteres en formato UNICODE, dos bytes por cada letra. Es


recomendable utilizar este tipo de datos cuando los valores que vayamos a almacenar
puedan pertenecer a diferente idomas.
Nvarchar(n).Almacena n caracteres en formato UNICODE, dos bytes por cada letra.
Es recomendable utilizar este tipo de datos cuando los valores que vayamos a
almacenar puedan pertenecer a diferente idomas.
Nvarchar(max).Igual que varchar, pero al declararse como max puede almacenar
-1 bytes.

231

Tipos de datos de fecha.


Datetime. Almacena fechas con una precision de milisegundo. Debe usarse para
fechas muy especificas.
SmallDatetime. Almacena fechas con una precision de minuto, por lo que ocupa la
mitad de espacio de que el tipo datetime, para tablas que puedan llegar a tener
muchos datos es un factor a tener muy en cuenta.
TimeStamp.Se utiliza para marcar un registro con la fecha de insercin - actualizaci
n. El tipo timestamp se actualiza automticamente cada vez que insertamos o
modificamos los datos.

Tipos de datos binarios


Binary. Se utiliza para almacenar datos binarios de longitud fija, con una longitud m
xima de 8000 bytes.
Varbinary. Se utiliza para almacenar datos binarios de longitud variable, con una
longitud mxima de 8000 bytes..Es muy similar a binary, salvo que varbinary utiliza
menos espacio en disco.
Varbinary(max).Igual que varbinary, pero puede almacenar 231-1 bytes

Tipo de datos XML.


XML.Una de las grandes mejoras que incorpora SQL Server 2005 es el soporte nativo
para XML. Como podemos deducir, este tipo de datos se utiliza para almacenar XML.

Ejemplos:

www.templatesclarion.com.ar

28

Curso SQL + Clarion - www.templatesclarion.com.ar

DECLARE @bit bit,


@tinyint tinyint,
@smallint smallint,
@int int,
@bigint bigint,
@decimal decimal(10,3), -- 10 digitos, 7 enteros y
@real real,
@double float(53),
@money money
set @bit = 1
print @bit

-- 3 decimales

set @tinyint = 255


print @tinyint
set @smallint = 32767
print @smallint
set @int = 642325
print @int
set @decimal = 56565.234
print @decimal

-- Punto como separador decimal

set @money = 12.34


print @money
1.3.3.1

Campos Identity
SQL Server nos da la posibilidad de generar valores sobre las columnas de la siguiente
manera:

Con la Propiedad identity

Con la funcin NEWID

Con el tipo de dato uniqueidentifier

Propiedad Identity
La propiedad identity puede ser utilizada para crear columnas que contienen
valores secuenciales que identifican a cada columna insertada en la tabla y
frecuentemente estas son utilizadas como llaves primarias.
Las ventajas de la propiedad identity es que se reduce el costo y mejora el
performance. Simplifica la programacin, mantiene las llaves primarias con
valores cortos y reduce cuellos de botella en las transacciones.
Sintaxis
CREATE TABLE table
(column_name data_type
[ IDENTITY [(seed, increment)]] NOT NULL )
Puntos a considerar en los campos identity

Solo se permite un campo identity en una tabla

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

29

Debe ser usada con el tipo de datos integre(int, bigint, smallint o tinyint),
numeric o decimal. El tipo de datos numerica y decima deben ser especificados
con una escala de 0.

No pueden ser actualizados

Se puede utilizar IDENTITYCOL en el lugar de la columna en un query. Esto


referencia a la columna con la propiedad identity sin la necesidad de conocer el
nombre de la columna.

No permite el uso de valores nulos

Se puede extraer informacin sobre la propiedad identity de diferentes formas:

Existen dos funciones que obtienen informacin sobre la definicin de un identity:


IDENT_SEED(regresa el valor con el que inicia el identity) y IDENT_INCR(regresa
el valor con el que se incrementa el identity).

Se pueden extraer datos de las columnas identity utilizando la variable global


@@identity. Esta contiene el ltimo valor insertado en una columna identity
durante una sesin.

SCOPE_INDENTITY regresa el ltimo valor identity insertado en una columna en el


mismo scop. Un scop puede ser un store procedure, trigger, funcin o batch.

IDENT_CURRENT regresa el ltimo valor del identity generado para una tabla en
especifico en cualquier sesin y cualquier scop.

La propiedad identity puede ser manipulada de diferentes formas:

Se puede permitir insertar valores especficos en los campos identity de una tabla
habilitando la opcin IDENTITY_INSERT. Cuando esta opcin esta en ON, las
sentencias insert deben de contener un valor en la columna con identity.

Para verificar y corregir el valor actual del identity de una columna, se puede
utilizar el DBCC CHECKIDENT. Este te permite comparar los valores actuales del
identity con el valor mximo de la columna con identity.

NOTA: La propiedad identity no garantiza que los registros sea nicos, para esto genere
un ndice nico sobre el campo identity.
Ejemplo
En este ejemplo se crea una tabla con dos campos, userid y nombre. La propiedad
identity es utilizada en el campo userid para incrementar el valor automticamente cada
vez que se inserte un registro. El inicio del identity es 100 y el incremento 5. De esta
manera los valores seran 100, 105, 110, 115, etc. Utilizando un incremento de 5
permite insertar registros entre los valores posteriormente.
CREATE TABLE Class
(userid int IDENTITY(100, 5) NOT NULL, Name varchar(16))

La funcin NEWID y el tipo de dato uniqueidentifier


La funcin NEWID y el tipo de dato uniqueidentifier se utilizan de manera conjunta y se
deben de utilizar cuando la informacin que se colecta proviene de muchas tablas, insert

www.templatesclarion.com.ar

30

Curso SQL + Clarion - www.templatesclarion.com.ar

ndolas en una sola requiriendo que cada uno de los registros sea nico.

El tipo de dato uniqueidentifier almacena un valor nico como un string binario de


16 bytes. Este tipo de dato es utilizado para almacenar un identificador global
(Global Unique Identifier (GUID)).

La funcin NEWID crea un identificador nico GUID que puede ser almacenado en
un tipo de dato uniqueidentifier.

El tipo de dato uniqueidentifier no genera automticamente nuevos ID's para los


registros insertados como lo hace la propiedad identity. Para obtener un nuevo
valor se debe definir la tabla con un constraint que especifique la funcin NEWID
vomo default. Cuando se genere una sentencia insert, se debe especifica la funci
n NEWID.

Ejemplo
CREATE TABLE Customer
(CustID uniqueidentifier NOT NULL DEFAULT NEWID(), CustName char(30) NOT
NULL)

1.3.4

Lenguaje de Definicin de datos (LDD)


Existen cuatro operaciones bsicas dentro de este lenguaje: CREATE , ALTER
y TRUNCATE

1.3.4.1

, DROP

CREATE
Este comando crea un objeto dentro de la base de datos. Puede ser una tabla, vista,
ndice, trigger, funcin, procedimiento o cualquier otro objeto que el motor de la base de
datos soporte.
Por Ejemplo (creacin de una tabla):
CREATE TABLE TABLA_NOMBRE ( ci integer not null, nombre VARCHAR (50),
fecha_nac DATE NOT NULL, PRIMARY KEY (my_field1, my_field2) )

1.3.4.2

ALTER
Este comando permite modificar la estructura de un objeto. Se pueden agregar/quitar
campos a una tabla, modificar el tipo de un campo, agregar/quitar ndices a una tabla,
modificar un trigger, etc.
Por Ejemplo (agregar columna a una tabla):
ALTER TABLE TABLA_NOMBRE ( ADD NUEVO_CAMPO INT UNSIGNED )

1.3.4.3

DROP
Este comando elimina un objeto de la base de datos.Puede ser una tabla, vista, ndice,
trigger, funcin, procedimiento o cualquier otro objeto que el motor de la base de datos
soporte. Se puede combinar con la sentencia ALTER.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

31

Por Ejemplo :
DROP TABLE TABLA_NOMBRE
1.3.4.4

TRUNCATE
Este comando trunca todo el contenido de una tabla. La ventaja sobre el comando
DELETE, es que si se quiere borrar todo el contenido de la tabla, es mucho ms rpido,
especialmente si la tabla es muy grande, la desventaja es que TRUNCATE solo sirve
cuando se quiere eliminar absolutamente todos los registros, ya que no se permite la cl
usula WHERE.
Por Ejemplo :
TRUNCATE TABLE TABLA_NOMBRE

1.3.5

Lenguaje de Manipulacin de Datos Nivel Bsico


Existen cuatro operaciones bsicasen el lenguaje de Manipulacion de Datos: SELECT,
INSERT, UPDATE y DELETE.

1.3.5.1

Recuperar Datos con SELECT


Una consulta es una peticin de datos almacenados en el motor SQL.
La instruccin SELECT recupera los datos de SQL Server y los presenta al usuario en uno
o ms conjuntos de resultados. Un conjunto de resultados es una organizacin tabular de
los datos obtenidos de SELECT. Al igual que una tabla de SQL, el conjunto de resultados
est formado por columnas y filas.
La sintaxis completa de la instruccin SELECT es compleja, aunque la mayor parte de las
instrucciones SELECT describen las cuatro propiedades principales de un conjunto de
resultados:
El nmero y atributos de las columnas del conjunto de resultados. Estos atributos se
definen para cada columna del conjunto de resultados:
El tipo de datos de la columna.
El tamao de la columna y, para las columnas numricas, la precisin y escala.
El origen del valor de los datos devueltos en la columna.
Las tablas cuyos datos del conjunto de resultados se recuperan y cualquier relacin
lgica entre las tablas.
Las condiciones que deben cumplir las filas de las tablas de origen para satisfacer los
requisitos de la instruccin SELECT. Las filas que no cumplen las condiciones se
omiten.
La secuencia en la que se ordenan las filas del conjunto de resultados.
Por ejemplo esta instruccin SELECT busca el identificador del producto, el nombre y el
precio unitario de cualquier producto cuyo precio exceda de 40 dlares:
SELECT ProductID, ProductName, UnitPrice
FROM Products
WHERE UnitPrice > $40
ORDER BY UnitPrice ASC
Los nombres de columna enumerados despus de la palabra clave SELECT (ProductID,
ProductName y UnitPrice) forman la lista de seleccin. Esta lista especifica que el

www.templatesclarion.com.ar

32

Curso SQL + Clarion - www.templatesclarion.com.ar

conjunto de resultados tiene tres columnas, y cada columna tiene el nombre, tipo de
datos y tamao de la columna asociada de la tabla Products. Puesto que la clusula
FROM especifica slo una tabla base, todos los nombres de columna de la instruccin
SELECT hacen referencia a las columnas de esa tabla.
La clusula FROM enumera la tabla individual, Products, cuyos datos se van a recuperar.
La clusula WHERE especifica que las nicas filas de Products que cumplen los requisitos
de esta instruccin SELECT son aquellas en las que el valor de la columna UnitPrice
supera los 40 dlares.
La clusula ORDER BY especifica que el conjunto de resultados debe ordenarse en
secuencia ascendente segn el valor de la columna UnitPrice.

SELECT: Lista de seleccin de columnas


La lista de seleccin define las columnas del conjunto de resultados de una instruccin
SELECT. La lista de seleccin es una serie de expresiones separadas por comas. Cada
expresin define una columna del conjunto de resultados. Las columnas del conjunto de
resultados estn en el mismo orden que las expresiones de la lista de seleccin.
Los siguientes atributos de las columnas del conjunto de resultados se definen mediante
las expresiones de la lista de seleccin:
El tipo de datos, tamao, precisin y escala de la columna del conjunto de resultados
son los mismos que los de la expresin que define la columna.
El nombre de la columna del conjunto de resultados es el nombre asociado con la
expresin que define la columna. La palabra clave opcional AS se puede usar para
cambiar el nombre o para asignar uno, si la expresin no lo tiene.
Los valores de los datos de las columnas del conjunto de resultados se derivan de la
evaluacin de la expresin para cada fila del conjunto de resultados.
La lista de seleccin puede contener tambin palabras clave que controlen el formato
final del conjunto de resultados.
Entre los elementos de la lista de seleccin se pueden incluir:
Una expresin simple: una referencia a una funcin, una variable local, una constante
o una columna de una tabla o vista.
Una subconsulta escalar, que es una instruccin SELECT que da como resultado un
valor individual para cada fila del conjunto de resultados.
Una expresin compleja generada al usar operadores en una o ms expresiones
simples.
La palabra clave *, que especifica que se devolvern todas las columnas de una tabla.
La asignacin de variables con el formato @local_variable = expresin. La instruccin
SET @local_variable se puede usar tambin para la asignacin de variables.
La palabra clave IDENTITYCOL, que se resuelve como una referencia a la columna de la
tabla que tiene la propiedad IDENTITY. Por ejemplo, la propiedad IDENTITY ha sido
definida para la columna OrderID en la tabla Northwind Orders, igual que la expresin
Orders. IDENTITYCOL es igual a Orders.OrderID.
La palabra clave ROWGUILDCOL, que se resuelve como una referencia a la columna de
una tabla que tiene la propiedad ROWGUIDCOL.
Crear una nueva columna (con SELECT INTO) que use la propiedad IDENTITY,
mediante la sintaxis especificada. Por ejemplo, para crear una nueva columna llamada
counter en la tabla authors que sea de tipo int, empiece con el valor 100 y vaya
aumentndolo en 1 por cada nmero sucesivo; use counter = IDENTITY(int, 100, 1).
Agregar temporalmente una columna a los resultados de la consulta que designe si la
operacin CUBE o ROLLUP agreg la fila o no. Usar la palabra clave GROUPING.
En este ejemplo se muestran muchos de los elementos que se pueden encontrar en una
www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

33

lista de seleccin:
SELECT FirstName + ' ' + LastName AS "Employee Name",
IDENTITYCOL AS "Employee ID",
HomePhone,
Region,
10 AS Constant
FROM Northwind.dbo.Employees
ORDER BY LastName, FirstName ASC

Temas Relacionados:
FROM
WHERE y HAVING: Filtrar filas
ORDER BY
JOIN: Combinaciones
DISTINCT
TOP n

1.3.5.1.1 FROM

La clusula FROM es obligatoria en todas las instrucciones SELECT en las que se estn
recuperando datos de tablas o vistas.
Use la clusula FROM para enumerar las tablas y vistas que contienen columnas a las
que se hace referencia en la lista de seleccin y en la clusula WHERE. Los nombres de
las tablas y vistas se pueden sustituir con alias mediante la clusula AS.
La clusula FROM es una lista separada por comas de nombres de tablas, nombres de
vistas y clusulas JOIN.

La clusula FROM puede especificar:


Una o ms tablas o vistas. Por ejemplo:
SELECT *
FROM Shippers
Combinaciones de dos tablas o vistas:
SELECT Cst.CustomerID, Cst.CompanyName, Cst.ContactName,
Ord.ShippedDate, Ord.Freight
FROM Northwind.dbo.Orders AS Ord
JOIN
Northwind.dbo.Customers AS Cst
ON (Cst.CustomerID = Ord.CustomerID)
Una o ms tablas derivadas, que son instrucciones SELECT de la clusula FROM a las que
se hace referencia mediante un alias o un nombre definido por el usuario. El conjunto de
resultados de la instruccin SELECT de la clusula FROM forma una tabla usada por la
instruccin SELECT externa. Por ejemplo, esta instruccin SELECT usa una tabla derivada
para averiguar si alguna tienda tiene todos los ttulos de libros de la base de datos pubs:
SELECT ST.stor_id, ST.stor_name
FROM stores AS ST,
(SELECT stor_id, COUNT(DISTINCT title_id) AS title_count

www.templatesclarion.com.ar

34

Curso SQL + Clarion - www.templatesclarion.com.ar

FROM sales
GROUP BY stor_id
) AS SA
WHERE ST.stor_id = SA.stor_id
AND SA.title_count = (SELECT COUNT(*) FROM titles)

Instrucciones SELECT sin clusulas FROM


Las instrucciones SELECT que no necesitan una clusula FROM son aqullas que no
seleccionan datos de ninguna tabla de la base de datos. Las siguientes son instrucciones
SELECT que slo seleccionan datos de las variables locales o de funciones Transact-SQL
que no operan en una columna, por ejemplo:
SELECT @MyIntVariable
SELECT @@VERSION
1.3.5.1.2 WHERE y HAVING: Filtrar filas

Las clusulas WHERE y HAVING de una instruccin SELECT controlan qu filas de las
tablas de origen se usan para generar el conjunto de resultados. WHERE y HAVING son
filtros. Especifican una serie de condiciones de bsqueda y para crear el conjunto de
resultados slo se usan las filas que cumplan los trminos de dichas condiciones. Las
filas que cumplen las condiciones de bsqueda se dice que estn calificadas para
participar en el conjunto de resultados.
Por ejemplo, la clusula WHERE de esta instruccin SELECT slo califica las filas en las
que la regin sea Washington State:
SELECT CustomerID, CompanyName
FROM Northwind.dbo.Customers
WHERE Region = 'WA'
La clusula HAVING se usa normalmente junto con la clusula GROUP BY, aunque se
puede especificar sin GROUP BY. La clusula HAVING especifica otros filtros que se
aplican despus de los de la clusula WHERE. Por ejemplo, esta clusula WHERE slo
califica los pedidos de un producto cuyo precio unitario supere los 100 dlares, y la
clusula HAVING restringe posteriormente el resultado a aquellos pedidos que incluyan
ms de 100 unidades:
SELECT OrdD1.OrderID AS OrderID,
SUM(OrdD1.Quantity) AS "Units Sold",
SUM(OrdD1.UnitPrice * OrdD1.Quantity) AS Revenue
FROM [Order Details] AS OrdD1
WHERE OrdD1.OrderID in (SELECT DISTINCT OrdD2.OrderID
FROM [Order Details] AS OrdD2
WHERE OrdD2.UnitPrice > $100)
GROUP BY OrdD1.OrderID
HAVING SUM(OrdD1.Quantity) > 100

Las condiciones de bsqueda o calificaciones de las clusulas WHERE y HAVING pueden


incluir:

Operadores de comparacin

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

35

(como =, < >, < y >). Por ejemplo, en la siguiente consulta se recuperan las filas de la tabla Products
SELECT ProductID, ProductName
FROM Northwind.dbo.Products
WHERE CategoryID = 2
ORDER BY ProductID

Intervalos
(BETWEEN y NOT BETWEEN). Por ejemplo, en esta consulta se recuperan las filas de la
tabla Products de las categoras 2 a 4.
SELECT CategoryID, ProductID, ProductName
FROM Northwind.dbo.Products
WHERE CategoryID BETWEEN 2 and 4
ORDER BY CategoryID, ProductID

Listas
(IN, NOT IN). Por ejemplo, en esta consulta se recuperan las filas de la tabla Products
donde Category ID coincida con algn Id. de la lista:
SELECT CategoryID, ProductID, ProductName
FROM Northwind.dbo.Products
WHERE CategoryID IN (1,4,5,7)
ORDER BY CategoryID, ProductID

Coincidencia de patrones
(LIKE y NOT LIKE). Por ejemplo, en esta consulta se recuperan las filas de la tabla
Products donde el nombre del producto empiece con las letras Ch.
SELECT CategoryID, ProductID, ProductName
FROM Northwind.dbo.Products
WHERE ProductName LIKE 'Ch%'
ORDER BY CategoryID, ProductID

Todos los registros


(=ALL, >ALL, <= ALL, ANY). Por ejemplo, en esta consulta se recuperan los Id. de los
pedidos y de los productos de la tabla Order Details donde la cantidad del producto
enviado sea mayor que la cantidad enviada de cualquier producto de la categora 1:
USE Northwind
GO
SELECT OrdD1.OrderID, OrdD1.ProductID
FROM "Order Details" OrdD1
WHERE OrdD1.Quantity > ALL
(SELECT OrdD2.Quantity
FROM "Order Details" OrdD2 JOIN Products Prd
ON OrdD2.ProductID = Prd.ProductID
WHERE Prd.CategoryID = 1)
GO

Combinaciones de estas condiciones


(AND, OR, NOT). Por ejemplo, en esta consulta se recuperan todos los productos en los
que la cantidad de productos almacenados sea inferior a la cantidad de pedidos, o el
producto venga del proveedor 15 y sea de la categora 4:
SELECT ProductID, ProductName
FROM Northwind.dbo.Products
WHERE UnitsInStock < ReorderLevel
OR (SupplierID = 15 AND CategoryID = 4)

www.templatesclarion.com.ar

36

Curso SQL + Clarion - www.templatesclarion.com.ar

1.3.5.1.3 ORDER BY

La clusula ORDER BY ordena los resultados de una consulta por una o ms columnas.
Una ordenacin puede ser ascendente (ASC) o descendente (DESC). Si no se especifica
ninguna, se supone que es ASC.

Ejemplos
En la consulta siguiente se devuelven los resultados ordenados de forma ascendente por
pub_id.
USE pubs
SELECT pub_id, type, title_id
FROM titles
ORDER BY pub_id
Si se nombra ms de una columna en la clusula ORDER BY, las ordenaciones se anidan.
La instruccin siguiente ordena las filas de la tabla titles, primero por editor, en orden
descendente; despus, por tipo, en orden ascendente, dentro de cada editor y,
finalmente, por precio (tambin en orden ascendente, porque no se especifica DESC).
USE pubs
SELECT pub_id, type, title_id, price
FROM titles
ORDER BY pub_id DESC, type, price
1.3.5.1.4 JOIN: Combinaciones

Las condiciones de combinacin se pueden especificar en las clusulas FROM o WHERE,


aunque se recomienda que se especifiquen en la clusula FROM. Las clusulas WHERE y
HAVING pueden contener tambin condiciones de bsqueda para filtrar an ms las filas
seleccionadas por las condiciones de combinacin.

Tipos de combinaciones
Combinaciones internas (la operacin de combinacin tpica, que usa algunos
operadores de comparacin como = o <>). En este tipo se incluyen las combinaciones
equivalentes y las combinaciones naturales. Las combinaciones internas usan un
operador de comparacin para hacer coincidir las filas de dos tablas segn los valores
de las columnas comunes de cada tabla. Un ejemplo sera recuperar todas las filas en
las que el nmero de identificacin de estudiante es el mismo en las tablas students y
courses.
Combinaciones externas. Puede ser una combinacin externa izquierda, derecha o
completa. Las combinaciones externas se especifican en la clusula FROM con uno de
los siguientes conjuntos de palabras clave:
LEFT JOIN o LEFT OUTER JOIN: El conjunto de resultados de una combinacin externa
izquierda incluye todas las filas de la tabla de la izquierda especificada en la clusula
LEFT OUTER, y no slo aquellas en las que coincidan las columnas combinadas. Cuando
una fila de la tabla de la izquierda no tiene filas coincidentes en la tabla de la derecha,
la fila asociada del conjunto de resultados contiene valores NULL en todas las columnas
de la lista de seleccin que procedan de la tabla de la derecha.
RIGHT JOIN o RIGHT OUTER JOIN: Una combinacin externa derecha es el inverso de

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

37

una combinacin externa izquierda. Se devuelven todas las filas de la tabla de la


derecha. Cada vez que una fila de la tabla de la derecha no tenga correspondencia en
la tabla de la izquierda, se devuelven valores NULL para la tabla de la izquierda.
FULL JOIN o FULL OUTER JOIN: Una combinacin externa completa devuelve todas las
filas de las tablas de la izquierda y la derecha. Cada vez que una fila no tenga
coincidencia en la otra tabla, las columnas de la lista de seleccin de la otra tabla
contendrn valores NULL. Cuando haya una coincidencia entre las tablas, la fila
completa del conjunto de resultados contendr los valores de datos de las tablas base.
Combinaciones cruzadas: Las combinaciones cruzadas devuelven todas las filas de la
tabla izquierda y cada fila de la tabla izquierda se combina con todas las filas de la
tabla de la derecha. Las combinaciones cruzadas se llaman tambin productos
cartesianos.

Utilizar combinaciones internas


Una combinacin interna es aqulla en la que los valores de las columnas que se estn
combinando se comparan mediante un operador de comparacin.
En el estndar SQL-92, las combinaciones internas se pueden especificar en las clusulas
FROM o WHERE. ste es el nico tipo de combinacin que SQL-92 admite en la clusula
WHERE. Las combinaciones internas especificadas en la clusula WHERE se conocen
como combinaciones internas al estilo antiguo.
Esta consulta de Transact-SQL es un ejemplo de una combinacin interna:
USE pubs
SELECT *
FROM authors AS a INNER JOIN publishers AS p
ON a.city = p.city
ORDER BY a.au_lname DESC
Esta combinacin interna se conoce como una combinacin equivalente. Devuelve todas
las columnas de ambas tablas y slo devuelve las filas en las que haya un valor igual en
la columna de la combinacin.
El siguiente es el conjunto de resultados:
au_id
----------238-95-7766
409-56-7008
state
----CA
CA

zip
----94705
94705

au_lname
-------Carson
Bennet
contract
-------1
1

au_fname
-------Cheryl
Abraham

pub_id
-----1389
1389

phone
-----------415 548-7723
415 658-9932

address
city
--------------- -------589 Darwin Ln.
Berkeley
6223 Bateman St. Berkeley

pub_name
--------------------Algodata Infosystems
Algodata Infosystems

city
-------Berkeley
Berkeley

state
----CA
CA

country
------USA
USA

En el conjunto de resultados, la columna city aparece dos veces. Puesto que no tiene
sentido repetir la misma informacin, se puede eliminar una de estas dos columnas
idnticas si se cambia la lista de seleccin. El resultado se llama combinacin natural. La
consulta anterior de Transact-SQL se puede volver a formular para que forme una
combinacin natural. Por ejemplo:
USE pubs

www.templatesclarion.com.ar

38

Curso SQL + Clarion - www.templatesclarion.com.ar

SELECT p.pub_id, p.pub_name, p.state, a.*


FROM publishers p INNER JOIN authors a
ON p.city = a.city
ORDER BY a.au_lname ASC, a.au_fname ASC
El siguiente es el conjunto de resultados:
pub_id pub_name
------ --------------Algodata Infosystems CA
1389
Algodata Infosystems

state
au_id
au_lname au_fname
-------- ----------- -------- -------- 1389
409-56-7008 Bennet
Abraham
CA
238-95-7766 Carson
Cheryl

phone
address
--------------- ------------415 658-9932 6223 Bateman St.
415 548-7723 589 Darwin Ln.

city
-------Berkeley
Berkeley

state
----CA
CA

zip
----94705
94705

contract
--------1
1

(2 row(s) affected)

En este ejemplo, publishers.city no aparece en los resultados.

Combinaciones con operadores distintos de igual


Tambin se puede combinar valores de dos columnas que no son iguales. Los mismos
operadores y predicados usados para las combinaciones internas se pueden utilizar para
las combinaciones no igual (< >). Para obtener ms informacin acerca de los
operadores y predicados disponibles que se pueden usar en las combinaciones, consulte
Utilizar operadores en expresiones y WHERE.
Este ejemplo de Transact-SQL es de una combinacin mayor que (>) que busca autores
de New Moon que viven en estados cuyo nombre est en orden alfabtico despus de
Massachusetts, donde se encuentra New Moon Books.
USE pubs
SELECT p.pub_name, p.state, a.au_lname, a.au_fname, a.state
FROM publishers p INNER JOIN authors a
ON a.state > p.state
WHERE p.pub_name = 'New Moon Books'
ORDER BY au_lname ASC, au_fname ASC
El siguiente es el conjunto de resultados:
pub_name
---------------New Moon Books
New Moon Books
New Moon Books
New Moon Books
New Moon Books
New Moon Books

state
au_lname
------- -------------------MA
Blotchet-Halls
MA
del Castillo
MA
Greene
MA
Panteley
MA
Ringer
MA
Ringer

au_fname
-------------------Reginald
Innes
Morningstar
Sylvia
Albert
Anne

state
----OR
MI
TN
MD
UT
UT

(6 row(s) affected)

Combinaciones con el operador no igual


La combinacin no igual (< >) se usa con poca frecuencia. Como regla general, las
combinaciones no igual slo tienen sentido cuando se usan con una autocombinacin. Por
ejemplo, la combinacin no igual de Transact-SQL y la autocombinacin siguientes se
usan para buscar categoras de dos o ms libros baratos (menos de 15 dlares) de
distintos precios:
USE pubs

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

39

SELECT DISTINCT t1.type, t1.price


FROM titles t1 INNER JOIN titles t2
ON t1.type = t2.type
AND t1.price <> t2.price
WHERE t1.price < $15 AND t2.price < $15
Nota: La expresin NOT column_name = column_name es equivalente a column_name <
> column_name.
En el siguiente ejemplo de Transact-SQL se usa una combinacin no igual que se
combina con una autocombinacin para buscar todas las filas de la tabla titleauthor en la
que dos o ms filas tengan el mismo title_id pero distintos nmeros de au_id (es decir,
libros con ms de un autor):
USE pubs
SELECT DISTINCT t1.au_id, t1.title_id
FROM titleauthor t1 INNER JOIN titleauthor t2
ON t1.title_id = t2.title_id
WHERE t1.au_id <> t2.au_id
ORDER BY t1.au_id
El siguiente es el conjunto de resultados:
au_id
----------213-46-8915
267-41-2394
267-41-2394
409-56-7008
427-17-2319
472-27-2349
672-71-3249
722-51-5454
724-80-9391
724-80-9391
756-30-7391
846-92-7186
899-46-2035
899-46-2035
998-72-3567

title_id
-------BU1032
BU1111
TC7777
BU1032
PC8888
TC7777
TC7777
MC3021
BU1111
PS1372
PS1372
PC8888
MC3021
PS2091
PS2091

(15 row(s) affected)

Utilizar combinaciones externas


Las combinaciones internas slo devuelven filas cuando hay una fila de ambas tablas,
como mnimo, que coincide con la condicin de la combinacin. Las combinaciones
internas eliminan las filas que no coinciden con alguna fila de la otra tabla. Sin embargo,
las combinaciones externas devuelven todas las filas de una de las tablas o vistas
mencionadas en la clusula FROM, como mnimo, siempre que tales filas cumplan con
alguna de las condiciones de bsqueda de WHERE o HAVING. Todas las filas se
recuperarn de la tabla izquierda a la que se haya hecho referencia con una combinacin
externa izquierda, y de la tabla derecha a la que se haya hecho referencia con una
combinacin externa derecha. En una combinacin externa completa, se devuelven todas
las filas de ambas tablas.
SQL Server utiliza las siguientes palabras clave de SQL-92 para las combinaciones
externas especificadas en una clusula FROM:

www.templatesclarion.com.ar

40

Curso SQL + Clarion - www.templatesclarion.com.ar

LEFT OUTER JOIN o LEFT JOIN


RIGHT OUTER JOIN o RIGHT JOIN
FULL OUTER JOIN o FULL JOIN
SQL Server admite tanto la sintaxis de combinaciones externas de SQL-92 como la
sintaxis heredada para especificar las combinaciones externas que se basan en la
utilizacin de los operadores *= y =* en la clusula WHERE. Se recomienda utilizar a
sintaxis de SQL-92 porque no est sujeta a las ambigedades que se producen, en
ocasiones, en las combinaciones externas heredadas de Transact-SQL.

Utilizar combinaciones exteriores izquierdas


Imagine una combinacin de la tabla authors y de la tabla publishers en sus columnas
city. Los resultados slo muestran los autores que viven en ciudades donde hay algn
editor (en este caso, Abraham Bennet y Cheryl Carson).
Para incluir todos los autores en el resultado, con independencia de que un editor se
encuentre o no en la misma ciudad, use una combinacin exterior izquierda de SQL-92. A
continuacin se muestra la consulta y los resultados de la combinacin externa izquierda
de Transact-SQL:
USE pubs
SELECT a.au_fname, a.au_lname, p.pub_name
FROM authors a LEFT OUTER JOIN publishers p
ON a.city = p.city
ORDER BY p.pub_name ASC, a.au_lname ASC, a.au_fname ASC
El siguiente es el conjunto de resultados:
au_fname
-------------------Reginald
Michel
Innes
Ann
Marjorie
Morningstar
Burt
Sheryl
Livia
Charlene
Stearns
Heather
Michael
Sylvia
Albert
Anne
Meander
Dean
Dirk
Johnson
Akiko
Abraham
Cheryl
(23 row(s) affected)

www.templatesclarion.com.ar

au_lname
-----------------------------Blotchet-Halls
DeFrance
del Castillo
Dull
Green
Greene
Gringlesby
Hunter
Karsen
Locksley
MacFeather
McBadden
O'Leary
Panteley
Ringer
Ringer
Smith
Straight
Stringer
White
Yokomoto
Bennet
Carson

pub_name
----------------NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
Algodata Infosystems
Algodata Infosystems

Programando con CLARION + SQL (MS-SQL)

41

LEFT OUTER JOIN incluye en el resultado todas las filas de la tabla authors, tanto si hay
una coincidencia en la columna city de la tabla publishers como si no la hay. Observe
que, en los resultados, no hay datos coincidentes con la mayor parte de los autores
enumerados, con lo que estas filas contienen valores NULL en la columna pub_name.

Utilizar combinaciones exteriores derechas


Imagine una combinacin de la tabla authors y de la tabla publishers en sus columnas
city. Los resultados slo muestran los autores que viven en ciudades donde haya algn
editor (en este caso, Abraham Bennet y Cheryl Carson). El operador de combinacin
exterior derecha de SQL-92, RIGHT OUTER JOIN, indica que todas las filas de la segunda
tabla se deben incluir en los resultados, con independencia de si hay datos coincidentes
en la primera tabla.
Para incluir todos los editores en los resultados, sin tener en cuenta si hay un editor en la
ciudad, use una combinacin externa derecha de SQL-92. A continuacin se muestra la
consulta de Transact-SQL y los resultados de la combinacin externa derecha:
USE pubs
SELECT a.au_fname, a.au_lname, p.pub_name
FROM authors AS a RIGHT OUTER JOIN publishers AS p
ON a.city = p.city
ORDER BY p.pub_name ASC, a.au_lname ASC, a.au_fname ASC
El siguiente es el conjunto de resultados:
au_fname
-------------------Abraham
Cheryl
NULL
NULL
NULL
NULL
NULL
NULL
NULL

au_lname
-----------------------Bennet
Carson
NULL
NULL
NULL
NULL
NULL
NULL
NULL

pub_name
-------------------Algodata Infosystems
Algodata Infosystems
Binnet & Hardley
Five Lakes Publishing
GGG&G
Lucerne Publishing
New Moon Books
Ramona Publishers
Scootney Books

(9 row(s) affected)

Una combinacin externa se puede restringir an ms si se utiliza un predicado (como


comparar la combinacin con una constante). En este ejemplo se muestra la misma
combinacin externa derecha, pero se eliminan todos los ttulos de los que se han
vendido menos de 50 copias:
USE pubs
SELECT s.stor_id, s.qty, t.title
FROM sales s RIGHT OUTER JOIN titles t
ON s.title_id = t.title_id
AND s.qty > 50
ORDER BY s.stor_id ASC
El siguiente es el conjunto de resultados:
stor_id qty
title
------- ------ --------------------------------------------------------(null) (null) But Is It User Friendly?
(null) (null) Computer Phobic AND Non-Phobic Individuals: Behavior
Variations

www.templatesclarion.com.ar

42

Curso SQL + Clarion - www.templatesclarion.com.ar

(null)
(null)
(null)
7066
(null)
(null)
(null)
(null)
(null)
(null)
(null)
(null)
(null)
(null)
(null)
(null)

(null) Cooking with Computers: Surreptitious Balance Sheets


(null) Emotional Security: A New Algorithm
(null) Fifty Years in Buckingham Palace Kitchens
75
Is Anger the Enemy?
(null) Life Without Fear
(null) Net Etiquette
(null) Onions, Leeks, and Garlic: Cooking Secrets of the
Mediterranean
(null) Prolonged Data Deprivation: Four Case Studies
(null) Secrets of Silicon Valley
(null) Silicon Valley Gastronomic Treats
(null) Straight Talk About Computers
(null) Sushi, Anyone?
(null) The Busy Executive's Database Guide
(null) The Gourmet Microwave
(null) The Psychology of Computer Cooking
(null) You Can Combat Computer Stress!

(18 row(s) affected)

Para ver ms informacin acerca de los predicados, consulte WHERE.

Utilizar combinaciones externas completas


Para retener la informacin que no coincida al incluir las filas no coincidentes en los
resultados de una combinacin, utilice una combinacin externa completa. Microsoft
SQL Server 2000 proporciona el operador de combinacin externa completa, FULL
OUTER JOIN, que incluye todas las filas de ambas tablas, con independencia de que la
otra tabla tenga o no un valor coincidente.
Imagine una combinacin de la tabla authors y de la tabla publishers en sus columnas
city. Los resultados slo muestran los autores que viven en ciudades donde hay algn
editor (en este caso, Abraham Bennet y Cheryl Carson). El operador de combinacin
externa completa de SQL-92, FULL OUTER JOIN, indica que todas las filas de ambas
tablas se van a incluir en los resultados, con independencia de que haya datos
coincidentes en las tablas.
Para incluir todos los editores y todos los autores en el resultado, sin tener en cuenta si
una ciudad tiene un editor que se encuentra en la misma ciudad, o si un editor se
encuentra en la misma ciudad, use una combinacin externa completa. A continuacin se
muestra la consulta y los resultados de la combinacin externa completa de
Transact-SQL:
USE pubs
SELECT a.au_fname, a.au_lname, p.pub_name
FROM authors a FULL OUTER JOIN publishers p
ON a.city = p.city
ORDER BY p.pub_name ASC, a.au_lname ASC, a.au_fname ASC
El siguiente es el conjunto de resultados:
au_fname
-------------------Reginald
Michel
Innes
Ann
Marjorie
Morningstar

www.templatesclarion.com.ar

au_lname
---------------------------Blotchet-Halls
DeFrance
del Castillo
Dull
Green
Greene

pub_name
-------------------NULL
NULL
NULL
NULL
NULL
NULL

Programando con CLARION + SQL (MS-SQL)

Burt
Sheryl
Livia
Charlene
Stearns
Heather
Michael
Sylvia
Albert
Anne
Meander
Dean
Dirk
Johnson
Akiko
Abraham
Cheryl
NULL
NULL
NULL
NULL
NULL
NULL
NULL

Gringlesby
Hunter
Karsen
Locksley
MacFeather
McBadden
O'Leary
Panteley
Ringer
Ringer
Smith
Straight
Stringer
White
Yokomoto
Bennet
Carson
NULL
NULL
NULL
NULL
NULL
NULL
NULL

43

NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
Algodata Infosystems
Algodata Infosystems
Binnet & Hardley
Five Lakes Publishing
GGG&G
Lucerne Publishing
New Moon Books
Ramona Publishers
Scootney Books

Utilizar combinaciones cruzadas


Una combinacin cruzada que no tenga una clusula WHERE produce el producto
cartesiano de las tablas involucradas en la combinacin. El tamao del conjunto de
resultados de un producto cartesiano es igual al nmero de filas de la primera tabla
multiplicado por el nmero de filas de la segunda tabla. A continuacin se muestra un
ejemplo de una combinacin cruzada de Transact-SQL:
USE pubs
SELECT au_fname, au_lname, pub_name
FROM authors CROSS JOIN publishers
ORDER BY au_lname DESC

Utilizar autocombinaciones
Una tabla se puede combinar consigo misma en una autocombinacin. Por ejemplo,
puede usar una autocombinacin para averiguar qu autores de Oakland, California,
viven en la misma rea de cdigo postal.
Puesto que esta consulta conlleva una combinacin de la tabla authors consigo misma, la
tabla authors aparece en dos funciones. Para distinguir estas funciones, debe dar a la
tabla authors dos alias distintos (au1 y au2) en la clusula FROM. Estos alias se usan
para calificar los nombres de columna del resto de la consulta. ste es un ejemplo de la
instruccin de autocombinacin de Transact-SQL:
USE pubs
SELECT au1.au_fname, au1.au_lname, au2.au_fname, au2.au_lname
FROM authors au1 INNER JOIN authors au2
ON au1.zip = au2.zip
WHERE au1.city = 'Oakland'
ORDER BY au1.au_fname ASC, au1.au_lname ASC
El siguiente es el conjunto de resultados:
au_fname

www.templatesclarion.com.ar

au_lname

au_fname

au_lname

44

Curso SQL + Clarion - www.templatesclarion.com.ar

-------------------Dean
Dean
Dean
Dirk
Dirk
Dirk
Livia
Livia
Livia
Marjorie
Stearns

------------------Straight
Straight
Straight
Stringer
Stringer
Stringer
Karsen
Karsen
Karsen
Green
MacFeather

-------------------Dean
Dirk
Livia
Dean
Dirk
Livia
Dean
Dirk
Livia
Marjorie
Stearns

--------Straight
Stringer
Karsen
Straight
Stringer
Karsen
Straight
Stringer
Karsen
Green
MacFeather

(11 row(s) affected)

Para eliminar las filas del conjunto de resultados en las que los autores coinciden consigo
mismos y eliminar las filas que son idnticas, salvo en que el orden de los autores est
invertido, realice este cambio a la consulta de autocombinacin de Transact-SQL:
USE pubs
SELECT au1.au_fname, au1.au_lname, au2.au_fname, au2.au_lname
FROM authors au1 INNER JOIN authors au2
ON au1.zip = au2.zip
WHERE au1.city = 'Oakland'
AND au1.state = 'CA'
AND au1.au_id < au2.au_id
ORDER BY au1.au_lname ASC, au1.au_fname ASC
El siguiente es el conjunto de resultados:
au_fname
-----------Dean
Dean
Dirk

au_lname
----------------Straight
Straight
Stringer

au_fname
-------------------Dirk
Livia
Livia

au_lname
-------------------Stringer
Karsen
Karsen

(3 row(s) affected)

Ahora queda claro que Dean Straight, Dirk Stringer y Livia Karsen tienen todos el mismo
cdigo postal y viven en Oakland, California.
1.3.5.1.5 Utilizar alias de tablas

La legibilidad de una instruccin SELECT se puede mejorar si se proporciona un alias a la


tabla, conocido tambin como una variable de intervalo o nombre de correlacin. Un
alias de tabla se puede asignar con o sin la palabra clave AS:
table_name AS table alias
table_name table_alias
En el ejemplo siguiente, el alias p se asigna a publishers.
USE pubs
SELECT p.pub_id, p.pub_name
FROM publishers AS p

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

45

1.3.5.1.6 DISTINCT

La palabra clave DISTINCT elimina las filas duplicadas de un conjunto de resultados. Por
ejemplo, hay muchas filas en la tabla Northwind Orders con el mismo valor para
ShipCity. Para obtener una lista de los valores de ShipCity que hayan quitado los
duplicados:
SELECT DISTINCT ShipCity, ShipRegion
FROM Orders
ORDER BY ShipCity
.
1.3.5.1.7 TOP n

La palabra clave TOP especifica que se devolvern las primeras n filas del conjunto de
resultados. Si se especifica ORDER BY, las filas se seleccionan despus de que el
conjunto de resultados se haya ordenado. n es el nmero de filas que se va a devolver,
a menos que se especifique la palabra clave PERCENT. PERCENT especifica que n es el
porcentaje de filas del conjunto de resultados que se devuelve. Por ejemplo, esta
instruccin SELECT devuelve las primeras diez ciudades, en secuencia alfabtica, de la
tabla Orders:
SELECT DISTINCT TOP 10 ShipCity, ShipRegion
FROM Orders
ORDER BY ShipCity
1.3.5.2

Agregar filas con INSERT


La instruccin INSERT agrega una o ms filas nuevas a una tabla. Tratada de forma
simplificada, INSERT tiene la siguiente forma:
INSERT [INTO] table_or_view [(column_list)] data_values
La instruccin hace que data_values se inserte como una o ms filas en la tabla o vista
que se nombra. El argumento column_list es una lista separada por comas de los
nombres de tablas que se pueden utilizar para especificar las columnas para las que se
suministran datos. Si no se especifica column_list, todas las columnas de la tabla o vista
reciben datos.
Cuando una column_list no enumera todas las columnas de la tabla o vista, se inserta un
valor de NULL (o el valor predeterminado si se ha definido alguno para la columna) en
aquellas columnas que no se hayan enumerado en la lista. Todas las columnas no
especificadas en la lista de columnas deben permitir valores NULL o tener un valor
predeterminado asignado.
Las instrucciones INSERT no especifican valores para los siguientes tipos de columna
porque Microsoft SQL Server genera los valores de las columnas de estos tipos:
Columnas con una propiedad IDENTITY que genera los valores para la columna.

Columnas que tengan un valor predeterminado que utilice la funcin NEWID para generar
un valor GUID exclusivo.
Columnas calculadas.

www.templatesclarion.com.ar

46

Curso SQL + Clarion - www.templatesclarion.com.ar

Se trata de columnas virtuales que se definieron como una expresin calculada a partir
de una o varias columnas en la instruccin CREATE TABLE, como:
CREATE TABLE TestTable
(ColA INT PRIMARY KEY,
ColB INT NOT NULL,
ColC AS (ColA + ColB) * 2)
Los valores de datos suministrados deben coincidir con la lista de columnas. El nmero
de valores de datos debe ser el mismo que el nmero de columnas y el tipo de datos,
precisin y escala de cada valor de datos debe coincidir con los de la columna
correspondiente. Hay dos maneras de especificar los valores de datos:
Utilizar una clusula VALUES para especificar los valores de datos para una fila:
INSERT INTO MyTable (PriKey, Description)
VALUES (123, 'A description of part 123.')
Utilizar una subconsulta SELECT para especificar los valores de datos para una o ms filas.
INSERT INTO MyTable (PriKey, Description)
SELECT ForeignKey, Description
FROM SomeView

Insertar una fila mediante INSERT...Values


La palabra clave VALUES especifica los valores de una fila de una tabla. Los valores se
especifican como una lista separada por comas de expresiones escalares cuyos tipos de
datos, precisin y escala deben ser iguales, o implcitamente convertibles, a la columna
correspondiente de la lista de columnas. Si no se especifica una lista de columnas, los
valores deben especificarse en la misma secuencia que las columnas de la tabla o vista.

Ejemplo
Por ejemplo, para insertar un nuevo transportista en la tabla Shippers con la clusula VALUES:
INSERT INTO Northwind.dbo.Shippers (CompanyName, Phone)
VALUES (N'Snowflake Shipping', N'(503)555-7233')
Para esta insercin se necesita una lista de columnas porque la columna ShipperID tiene
la propiedad IDENTITY, con lo que no se pueden insertar valores en la misma.

Insertar filas mediante INSERT...SELECT


La subconsulta SELECT de la instruccin INSERT se puede utilizar para agregar valores
de una o ms tablas o vistas. Utilizar una subconsulta SELECT permite adems que se
inserte ms de una fila al mismo tiempo.

Ejemplo
Esta instruccin INSERT inserta en una tabla aparte algunos de los datos de todas las
filas de titles cuyo type sea cocina moderna:
USE pubs
INSERT INTO MyBooks
SELECT title_id, title, type
FROM titlesFROM titles
WHERE type = 'mod_cook'

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

47

La lista de seleccin de la subconsulta debe coincidir con la lista de columnas de la


instruccin INSERT. Si no se especifica ninguna lista de columnas, la lista de seleccin
debe coincidir con las columnas de la tabla o vista en la que se inserta.

Insertar filas mediante SELECT INTO


La instruccin SELECT INTO crea una nueva tabla y la llena con el conjunto de resultados
de SELECT. La estructura de la nueva tabla se define con los atributos de las expresiones
de la lista de seleccin

Ejemplo
SELECT Shippers.*, Link.Address, Link.City,
Link.Region, Link.PostalCode
INTO NewShippers
FROM Shippers
JOIN LinkServer.DB.dbo.Shippers AS Link
ON (Shippers.ShipperID = Link.ShipperID)
SELECT INTO se puede emplear para combinar datos de varias tablas o vistas en una
tabla. Tambin se puede utilizar para crear una nueva tabla que contenga datos
seleccionados de un servidor vinculado.

1.3.5.3

Cambiar datos con UPDATE


La instruccin UPDATE puede cambiar los valores de filas individuales, grupos de filas o
todas las filas de una tabla o vista. Tambin se puede utilizar para actualizar las filas de
un servidor remoto con un nombre de servidor vinculado o las funciones OPENROWSET,
OPENDATASOURCE y OPENQUERY, siempre que el proveedor de OLE DB utilizado para
obtener acceso al servidor remoto admita actualizaciones. Una instruccin UPDATE que
haga referencia a una tabla o vista slo puede cambiar los datos de una tabla a la vez.
La instruccin UPDATE tiene estas clusulas principales:
SET
Contiene una lista separada por comas de las columnas que deben actualizarse y el
nuevo valor de cada columna, con el formato column_name = expression. El valor
suministrado por las expresiones incluye elementos tales como constantes, valores
seleccionados de una columna de otra tabla o vista, o valores calculados por una
expresin compleja.
FROM
Identifica las tablas o vistas que suministran los valores de las expresiones de la clusula
SET, y las condiciones de combinacin opcional entre las tablas o vistas de origen.
WHERE
Especifica la condicin de bsqueda que define las filas de las tablas y vistas de origen
que estn calificadas para proporcionar valores para las expresiones de la clusula SET.
Esta instruccin de actualizacin aumenta el precio de todos los productos de Northwind
de la categora 2 en un 10 por ciento:
UPDATE Northwind.dbo.Products
SET UnitPrice = UnitPrice * 1.1

www.templatesclarion.com.ar

48

Curso SQL + Clarion - www.templatesclarion.com.ar

WHERE CategoryID = 2

Cambiar datos con la clusula SET


SET especifica las columnas que deben cambiarse y sus nuevos valores. Los valores de
las columnas especificadas se actualizan con los valores proporcionados en SET en todas
las filas que coincidan con la condicin de bsqueda de la clusula WHERE. Si no se
especifica una clusula WHERE, se actualizan todas las filas. Por ejemplo, si todas las
casas de publicacin de la tabla publishers trasladan sus oficinas principales a Atlanta,
Georgia, se utilizara esta instruccin UPDATE:
UPDATE publishers SET city = 'Atlanta', state = 'Georgia'
En una actualizacin se puede calcular y usar los valores de las columnas calculadas. Por
ejemplo, para doblar todos los precios de la tabla titles, la columna price de la tabla titles
se puede establecer a price * 2.
Ejemplo
Las expresiones utilizadas en la clusula SET pueden ser tambin subconsultas que slo
devuelven un valor; por ejemplo, si la base de datos Northwind tuviera una tabla
OrderSummary:
UPDATE OrderSummary
SET Last30Days =
(SELECT SUM(OrdDet.UnitPrice * OrdDet.Quantity)
FROM [Order Details] AS OrdDet
JOIN Orders AS Ord
ON (OrdDet.OrderID = Ord.OrderID
AND Ord.OrderDate > DATEADD(dd,-30,GETDATE()) ))

Cambiar datos con la clusula WHERE


La clusula WHERE realiza dos funciones:
Especifica las filas que deben actualizarse.
Indica las filas de las tablas de origen que se califican para suministrar los valores de la
actualizacin si se especifica tambin una clusula FROM.
Si no especifica una clusula WHERE, se actualizan todas las filas de la tabla.
Ejemplo
Esta instruccin UPDATE implementa un cambio de nombre para uno de los
transportistas (shippers):
UPDATE Northwind.dbo.Shippers
SET CompanyName = 'United Shippers'
WHERE CompanyName = 'United Packages'

Cambiar datos con la clusula FROM


Utilice la clusula FROM para extraer datos de una o ms tablas o vistas, e insertarlos en
la tabla que desea actualizar. Por ejemplo, cuando el autor Dirk Stringer consigue un
contrato, a su libro, The Psychology of Computer Cooking, se le asigna un nmero de
identificacin del ttulo en la tabla titles. La fila de Dirk de la tabla titleauthor se puede
actualizar si se agrega un nmero de identificacin de ttulo para este ltimo libro.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

49

Ejemplo
En el ejemplo siguiente se actualiza la fila de Dirk Stringer de la tabla titleauthor para
agregar el nmero de identificacin de ttulo de su ltimo libro:
UPDATE titleauthor
SET title_id = titles.title_id
FROM titles INNER JOIN titleauthor
ON titles.title_id = titleauthor.title_id
INNER JOIN authors
ON titleauthor.au_id = authors.au_id
WHERE titles.title = 'Net Etiquette'
AND au_lname = 'Locksley'

Cambiar datos con un cursor


Cuando utilice un cursor de servidor de Transact-SQL, podr actualizar la fila actual con
una instruccin UPDATE que incluya una clusula WHERE CURRENT OF. Los cambios
realizados con esta clusula afectan slo a la fila en la que est situado el cursor. Cuando
un cursor se basa en una combinacin, slo se modifica el table_name especificado en la
instruccin UPDATE. Las dems tablas que participan en el cursor no se ven afectadas.
USE Northwind
GO
DECLARE abc CURSOR FOR
SELECT CompanyName
FROM Shippers
OPEN abc
GO
FETCH NEXT FROM abc
GO
UPDATE Shippers SET CompanyName = N'Speedy Express, Inc.'
WHERE CURRENT OF abc
GO
CLOSE abc
DEALLOCATE abc
GO
1.3.5.4

Eliminar filas con DELETE


La instruccin DELETE quita una o varias filas de una tabla o vista. Una forma
simplificada de la sintaxis de DELETE es:
DELETE table_or_view FROM table_sources WHERE search_condition
table_or_view nombra la tabla o vista de la que se van a eliminar las filas. Se eliminan
todas las filas de table_or_view que renan los requisitos de la condicin de bsqueda de
la clusula WHERE. Si no se especifica una clusula WHERE, se eliminan todas las filas de
table_or_view. La clusula FROM especifica tablas o vistas adicionales y condiciones de
combinacin que pueden ser utilizadas por los predicados de la condicin de bsqueda de
la clusula WHERE para calificar las filas que deben ser eliminadas de table_or_view. Las
filas no se eliminan de las tablas mencionadas en la clusula FROM, slo de la tabla
mencionada en table_or_view.
Cualquier tabla de la que se hayan quitado todas las filas sigue permaneciendo en la

www.templatesclarion.com.ar

50

Curso SQL + Clarion - www.templatesclarion.com.ar

base de datos. La instruccin DELETE slo elimina filas de la tabla, y sta se debe quitar
de la base de datos mediante la instruccin DROP TABLE.

Para eliminar filas con DELETE


Esta secuencia de comandos muestra las tres instrucciones DELETE necesarias para
eliminar las filas asociadas con los productos suministrados por la empresa llamada
Lyngbysild de la base de datos Northwind. No sera una operacin empresarial tpica
porque conlleva la eliminacin de lneas de pedidos existentes, pero muestra una serie de
eliminaciones de distinta complejidad.
USE NorthwindUSE Northwind
GO
DELETE [Order Details]
FROM Suppliers, Products
WHERE Products.SupplierID = Suppliers.SupplierID
AND Suppliers.CompanyName = 'Lyngbysild'
AND [Order Details].ProductID = Products.ProductID
GO
DELETE Products
FROM Suppliers
WHERE Products.SupplierID = Suppliers.SupplierID
AND Suppliers.CompanyName = 'Lyngbysild'
GO
DELETE Suppliers
WHERE CompanyName = 'Lyngbysild'
GO

Eliminar filas de conjuntos de resultados


Las secuencias de comandos, procedimientos almacenados y desencadenadores de
Transact-SQL pueden utilizar la clusula WHERE CURRENT OF en una instruccin DELETE
para eliminar la fila de cursor en la que se encuentran posicionados, por ejemplo:
DECLARE abc CURSOR FOR
SELECT * FROM MyTable
OPEN abc
FETCH NEXT FROM abc
DELETE MyTable WHERE CURRENT OF abc
CLOSE abc
DEALLOCATE abc

Eliminar todas las filas con TRUNCATE TABLE


La instruccin TRUNCATE TABLE es un mtodo rpido y no registrado para eliminar todas
las filas de una tabla. Casi siempre es ms rpido que una instruccin DELETE sin
condiciones porque DELETE registra cada eliminacin de fila y TRUNCATE TABLE registra
slo la cancelacin de la asignacin de pginas completas de datos. TRUNCATE TABLE
libera inmediatamente todo el espacio ocupado por los datos e ndices de esa tabla.
Tambin se liberan las pginas de distribucin de todos los ndices.
Como en el caso de DELETE, la definicin de una tabla vaciada con TRUNCATE TABLE
permanece en la base de datos, junto con sus ndices y sus objetos asociados. Para
quitar la definicin de la tabla debe utilizarse la instruccin DROP TABLE.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

1.3.6

51

Trabajando con fechas


SQL Server tiene los tipos de datos datetime y smalldatetime para almacenar datos de
fecha y hora.
No hay tipos de datos diferentes de hora y fecha para almacenar slo horas o slo
fechas. Si slo se especifica una hora cuando se establece un valor datetime o
smalldatetime, el valor predeterminado de la fecha es el 1 de enero de 1900. Si slo se
especifica una fecha, la hora ser, de forma predeterminada, 12:00 a.m. (medianoche),
es decir, las 00:00.

Tipo de datos Datetime.


Datos de fecha y hora comprendidos entre el 1 de enero de 1753 y el 31 de diciembre de
9999, con una precisin de un trescientosavo de segundo, o 3,33 milisegundos.
SQL Server rechaza todos los valores que no puede reconocer como fechas entre 1753 y
9999.

Tipo de datos Smalldatetime.


Datos de fecha y hora desde el 1 de enero de 1900 al 6 de junio de 2079, con precisin
de minutos. Entonces si se utiliza un valor smalldatetime los segundos y milisegundos
son siempre 0.

Diferencia entre Datetime y Smalldatetime.


SQL Server almacena internamente los valores de tipo de datos datetime como enteros
de 4 bytes y los valores smalldatetime como enteros de 2 bytes.

Funciones de fecha y hora (Transact-SQL)


Estas funciones escalares realizan una operacin sobre un valor de fecha y hora de
entrada, y devuelven un valor de cadena, numrico o de fecha y hora:
DATEADD
DATEDIFF
DATENAME
DATEPART
GETDATE
DAY
MONTH
YEAR

Trabajando con fechas ...


Con algunos pequeos ejemplos trataremos de resolver los mayores problemas para
trabajar con estos tipos de datos.
Para ello utilizaremos las funciones CAST y CONVERT.

Separando Fecha y Hora.

www.templatesclarion.com.ar

52

Curso SQL + Clarion - www.templatesclarion.com.ar

Declare @Fecha datetime


Set @Fecha = Getdate()
Select Convert(Char(10), @Fecha,112) As SoloFecha, Convert(Char(8), @Fecha, 108) As So
SoloFecha SoloHora
---------- -------20010803 07:35:02
(1 row(s) affected)
Otra forma de conseguir el mismo resultado:
Declare @Fecha datetime
Set @Fecha = Getdate()
SELECT Convert(varchar, @Fecha, 3) AS SoloFecha, Convert(varchar, @Fecha, 8)

Operaciones con Fechas


(diferencia entre dos fechas).
Obtener diferencia de meses, dias, minutos, etc. entre dos fechas.
Para realizar operaciones entre dos fechas MSSQL tiene la funcin DATEDIFF. Veamos
algunos ejemplos de cmo utilizarla:
declare @FechaIngreso datetime
declare @FechaEgreso datetime
select @FechaIngreso = '19981231 15:15'
select @FechaEgreso = '20021005 10:10'
Select
DATEDIFF(dd, @FechaIngreso, @FechaEgreso) AS Dias,
DATEDIFF(mm, @FechaIngreso, @FechaEgreso) AS Meses,
DATEDIFF(mi, @FechaIngreso, @FechaEgreso) AS Minutos
Para obtener otras diferencias podemos recurrir a la siguiente tabla:
Parte de la fecha

Abreviaturas

ao

aa, aaaa

trimestre

tt, t

mes

mm, m

dia del ao

da, a

dia

dd, d

semana

sm, ss

hora

Hs

minuto

mi, n

segundo

ss, s

milisegundo

Ms

Otro ejemplo de DATEDIFF en donde recuperados los datos de la ultima semana

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

53

partiendo de la fecha del da:


SELECT TusDatos
FROM TuTabla
WHERE
DATEDIFF(dd, TuFecha, GetDate()) <= 7

Continuando con las operaciones con las fechas, veamos como podemos hacer para sumar, restar, da
select convert(varchar(12), DATEADD(month, -1, getdate()), 106) as 'un mes atrs'
select convert(varchar(12), DATEADD (week, -1, getdate()), 106) as 'una semana atrs'
select convert(varchar(12), DATEADD (day, -1, getdate()), 106) as 'ayer'

1.3.7

Elementos de sintaxis de Transact-SQL


Transact-SQL tiene varios elementos de sintaxis que son utilizados por, o influyen en, la
mayor parte de las instrucciones:

Identificadores
Son los nombres de objetos como tablas, vistas, columnas, bases de datos y servidores.

Tipos de datos
Definen el tipo de datos que contienen los objetos de datos como columnas, variables y
parmetros. La mayor parte de las instrucciones de Transact-SQL no hacen referencia
explcitamente a tipos de datos, sino que sus resultados estn influidos por las
interacciones entre los tipos de datos de los objetos a los que se hace referencia en la
instruccin.

Funciones
Son elementos de sintaxis que toman cero, uno o ms valores de entrada y devuelven un
valor escalar o un conjunto de valores en forma de tabla. Ejemplos de funciones son la
funcin SUM para sumar varios valores, la funcin DATEDIFF para determinar el nmero
de unidades de tiempo que separan dos fechas, la funcin @@SERVERNAME para
obtener el nombre de una instancia de Microsoft SQL Server.
Las funciones tambien pueden ser definidas por el usuario.

Expresiones
Son unidades de sintaxis que Microsoft SQL Server puede resolver en valores nicos.
Ejemplos de expresiones son las constantes, las funciones que devuelven un valor nico,
una referencia a una columna o una variable.

Operadores
Funcionan con una o ms expresiones individuales para formar una expresin ms
compleja. Por ejemplo, combinar el signo menos (-) con la constante 12 da como
resultado la constante -12. El signo de multiplicacin (*) de la expresin PriceColumn
*1.1 aumenta el precio en un 10 por ciento.

www.templatesclarion.com.ar

54

Curso SQL + Clarion - www.templatesclarion.com.ar

Comentarios
Son fragmentos de texto insertado en instrucciones o secuencias de comandos de
Transact-SQL para explicar el objetivo de la instruccin. Los comentarios no son
ejecutados por SQL Server.

Palabras clave reservadas


Son palabras reservadas que utiliza SQL Server y no deben emplearse como nombres de
objetos de una base de datos.

Valores NULL.
Los valores NULL son valores desconocidos. Puede usar valores NULL para indicar que la
informacin se proporcionar posteriormente. Por ejemplo, si la persona de contacto de
la empresa Leka Trading cambia y no se conoce la nueva persona de contacto, podra
indicar que su nombre es desconocido con un valor NULL.

Lenguaje de control de flujo.


El lenguaje de control de flujo permite al cdigo del programa emprender una accin en
funcin de que se cumpla o no alguna condicin. Por ejemplo, IF (si) la cantidad de
productos pedida es igual o menor que la cantidad de productos almacenada
actualmente, THEN (entonces) necesitamos pedir ms productos. Esto es fundamental en
la creacion de Stored Procedures y Triggers.

Utilizar variables y parmetros


Transact-SQL tiene varias formas de pasar datos entre instrucciones Transact-SQL. Entre
stas se encuentran:

Variables locales de Transact-SQL


Una variable de Transact-SQL es un objeto de lotes y secuencias de comandos
Transact-SQL que puede contener un valor de datos. Una vez que la variable se ha
declarado o definido, una instruccin Transact-SQL de un lote puede establecer un valor
para la variable y otra instruccin posterior del lote puede obtener el valor de la variable.
Por ejemplo:
DECLARE @EmpIDVar INT
SET @EmpIDVar = 1234
SELECT *
FROM Employees
WHERE EmployeeID = @EmpIDVar

Parmetros de Transact-SQL
Un parmetro es un objeto usado para pasar datos entre un procedimiento almacenado y
el lote o secuencia de comandos que lo ejecuta. Los parmetros pueden ser de entrada o
de salida. Por ejemplo:
CREATE PROCEDURE ParmSample
@EmpIDParm INT
AS

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

55

SELECT *
FROM Employees
WHERE EmployeeID = @EmpIDParm
GO
EXEC ParmSample @EmpIDParm = 1234
GO

Control de flujo
Transact-SQL proporciona palabras especiales que forman parte del llamado lenguaje de
control de flujo con el que se controla el flujo de la ejecucin de instrucciones
Transact-SQL, bloques de instrucciones y procedimientos almacenados. Estas palabras se
pueden usar en las instrucciones Transact-SQL ad hoc, en los lotes y en los
procedimientos almacenados.
Sin el lenguaje de control de flujo, las instrucciones Transact-SQL independientes se
ejecutan secuencialmente, tal como se producen. El lenguaje de control de flujo permite
que las instrucciones estn conectadas, se relacionen entre ellas y se hagan
interdependientes con construcciones similares a las de la programacin.

BEGIN...END
Las instrucciones BEGIN y END se usan para agrupar varias instrucciones Transact-SQL
en un bloque lgico. Use las instrucciones BEGIN y END en cualquier parte donde una
instruccin de control de flujo deba ejecutar un bloque con dos o ms instrucciones
Transact-SQL.
Por ejemplo, cuando una instruccin IF controla la ejecucin de una nica instruccin
Transact-SQL, no se necesita ninguna instruccin BEGIN o END:
IF (@@ERROR <> 0)
SET @ErrorSaveVariable = @@ERROR
Si @@ERROR es 0, slo se salta la instruccin individual SET.
Use las instrucciones BEGIN y END para hacer que la instruccin IF salte un bloque de
instrucciones cuando el resultado de la evaluacin sea FALSE (falso):
IF (@@ERROR <> 0)
BEGIN
SET @ErrorSaveVariable = @@ERROR
PRINT 'Error encountered, ' +
CAST(@ErrorSaveVariable AS VARCHAR(10))
END
Las instrucciones BEGIN y END deben usarse como un par: no se puede usar una sin la
otra. La instruccin BEGIN aparece sola en una lnea, seguida de un bloque de
instrucciones Transact-SQL. Finalmente, la instruccin END aparece sola en una lnea
para indicar el fin del bloque.
Las instrucciones BEGIN y END se usan cuando:
Es necesario que un bucle WHILE incluya un bloque de instrucciones.
Es necesario que un elemento de una funcin CASE incluya un bloque de instrucciones.
Es necesario que una clusula IF o ELSE incluya un bloque de instrucciones.

www.templatesclarion.com.ar

56

Curso SQL + Clarion - www.templatesclarion.com.ar

IF...ELSE
La instruccin IF se usa para probar una condicin. El control de flujo resultante depende
de si se especifica o no la instruccin ELSE opcional:
IF especificado sin ELSE: Cuando la instruccin IF da como resultado TRUE
(verdadero), se ejecuta la instruccin o bloque de instrucciones que sigue a la
instruccin IF. Cuando la instruccin IF da como resultado FALSE (falso), se salta la
instruccin o bloque de instrucciones que sigue a la instruccin IF.
IF especificado con ELSE: Cuando la instruccin IF da como resultado TRUE, se ejecuta
la instruccin o bloque de instrucciones que sigue a la instruccin IF. A continuacin, el
control salta al punto posterior a la instruccin o bloque de instrucciones que sigue a
ELSE. Cuando la instruccin IF da como resultado FALSE, se salta la instruccin o
bloque de instrucciones que sigue a IF y se ejecuta la instruccin o bloque de
instrucciones que sigue a la instruccin ELSE opcional.

Por ejemplo, si un procedimiento almacenado ha estado guardando los cdigos de error devueltos por
IF (@ErrorSaveVariable <> 0)
BEGIN
PRINT 'Errors encountered, rolling back.'
PRINT 'Last error encountered: ' +
CAST(@ErrorSaveVariable AS VARCHAR(10))
ROLLBACK
END
ELSE
BEGIN
PRINT 'No Errors encountered, committing.'
COMMIT
END
RETURN @ErrorSaveVariable

RETURN
La instruccin RETURN termina incondicionalmente una consulta, procedimiento
almacenado o lote. Ninguna de las instrucciones de un procedimiento almacenado o lote
que siga a la instruccin RETURN se ejecutar.
Cuando se usa en un procedimiento almacenado, la instruccin RETURN puede
especificar un valor entero para devolver a la aplicacin, lote o procedimiento que realiza
la llamada. Si no se especifica ningn valor en la instruccin RETURN, un procedimiento
almacenado devuelve el valor 0.
La mayor parte de los procedimientos almacenados siguen la convencin de usar el
cdigo de retorno para indicar si el procedimiento almacenado se ha ejecutado
correctamente o no. Los procedimientos almacenados devuelven el valor 0 cuando no se
encontraron errores. Cualquier valor distinto de cero indica que se produjo un error. Por
ejemplo:
USE Northwind
GO
-- Create a procedure that takes one input parameter
-- and returns one output parameter and a return code.
CREATE PROCEDURE SampleProcedure @EmployeeIDParm INT,
@MaxQuantity INT OUTPUT
AS
-- Declare and initialize a variable to hold @@ERROR.
www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

57

DECLARE @ErrorSave INT


SET @ErrorSave = 0
-- Do a SELECT using the input parameter.
SELECT FirstName, LastName, Title
FROM Employees
WHERE EmployeeID = @EmployeeIDParm
-- Save any nonzero @@ERROR value.
IF (@@ERROR <> 0)
SET @ErrorSave = @@ERROR
-- Set a value in the output parameter.
SELECT @MaxQuantity = MAX(Quantity)
FROM [Order Details]
IF (@@ERROR <> 0)
SET @ErrorSave = @@ERROR
-- Returns 0 if neither SELECT statement had
-- an error, otherwise returns the last error.
RETURN @ErrorSave
GO
Un lote o procedimiento almacenado de Transact-SQL que ejecuta un procedimiento
almacenado puede recuperar el cdigo de retorno en una variable de tipo entero:

DECLARE @ReturnStatus INT


DECLARE @MaxQtyVariable INT
EXECUTE @ReturnStatus = SampleProcedure @EmployeeIDParm = 9, @MaxQtyVariable = @MaxQua
-- Show the values returned.
PRINT ' '
PRINT 'Return code = ' + CAST(@ReturnStatus AS CHAR(10))
PRINT 'Maximum Quantity = ' + CAST(@MaxQtyVariable AS CHAR(10))
GO

WHILE...BREAK o CONTINUE
La instruccin WHILE repite una instruccin o bloque de instrucciones mientras la
condicin especificada siga siendo verdadera.
Con WHILE se usan normalmente dos instrucciones Transact-SQL: BREAK o CONTINUE.
La instruccin BREAK sale del bucle WHILE ms profundo, y la instruccin CONTINUE
reinicia un bucle WHILE. Un programa podra ejecutar una instruccin BREAK si, por
ejemplo, no hubiera ms filas que procesar. Una instruccin CONTINUE podra ejecutarse
si, por ejemplo, la ejecucin del cdigo debiera continuar.
Nota: Si una instruccin SELECT se usa como condicin de la instruccin WHILE, la
instruccin SELECT debe ir entre parntesis.
En este ejemplo se usa una instruccin WHILE para controlar el nmero de
recuperaciones realizadas:
USE Northwind
GO
DECLARE abc CURSOR FOR

www.templatesclarion.com.ar

58

Curso SQL + Clarion - www.templatesclarion.com.ar

SELECT * FROM Shippers


OPEN abc
FETCH NEXT FROM abc
WHILE (@@FETCH_STATUS = 0)
FETCH NEXT FROM abc
CLOSE abc
DEALLOCATE abc
GO

CASE
La funcin CASE es una expresin especial de Transact-SQL que permite que se muestre
un valor alternativo dependiendo del valor de una columna. Este cambio es temporal, con
lo que no hay cambios permanentes en los datos. Por ejemplo, la funcin CASE puede
mostrar California en un conjunto de resultados de una consulta de las filas que tengan
el valor CA en la columna state.
La funcin CASE est compuesta de:
La palabra clave CASE.
El nombre de columna que se va a transformar.
Clusulas WHEN que especifican las expresiones que se van a buscar y clusulas THEN
que especifican las expresiones que las van a reemplazar.
La palabra clave END.
Una clusula AS opcional que define un alias de la funcin CASE.
En este ejemplo se muestra, en el conjunto de resultados de la consulta, el nombre
completo del estado en el que vive cada autor:
SELECT au_fname, au_lname,
CASE state
WHEN 'CA' THEN 'California'
WHEN 'KS' THEN 'Kansas'
WHEN 'TN' THEN 'Tennessee'
WHEN 'OR' THEN 'Oregon'
WHEN 'MI' THEN 'Michigan'
WHEN 'IN' THEN 'Indiana'
WHEN 'MD' THEN 'Maryland'
WHEN 'UT' THEN 'Utah'
END AS StateName
FROM pubs.dbo.authors
ORDER BY au_lname

1.3.8

Consultas: Nivel avanzado

Usar funciones de agregado en la lista de seleccin


Agrupar filas con GROUP BY
Combinar resultados con UNION
1.3.8.1

Usar funciones de agregado en la lista de seleccin


Las funciones de agregado (SUM, AVG, COUNT, COUNT(*), MAX y MIN) generan valores
de resumen en los conjuntos de resultados de las consultas. Una funcin de agregado
(con la excepcin de COUNT(*)) procesa todos los valores seleccionados en una nica

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

59

columna para generar un nico resultado. Las funciones de agregado se pueden aplicar a
todas las filas de una tabla, a un subconjunto de la tabla especificado por una clusula
WHERE o a uno o varios grupos de filas de la tabla. Cuando se aplica una funcin de
agregado, se genera un valor individual por cada conjunto de filas.

COUNT(*)
COUNT(*) no requiere el parmetro expression porque no utiliza informacin acerca de
ninguna columna concreta. Cuenta el nmero total de filas que cumplen las calificaciones
de la consulta. COUNT(*) devuelve el nmero de filas que coinciden con las condiciones
de bsqueda especificadas en la consulta, sin eliminar los duplicados. Cuenta todas las
filas, incluidas las que contienen valores NULL. En esta consulta se busca el nmero total
de libros de la tabla titles:
USE pubs
SELECT COUNT(*)
FROM titles
El siguiente es el conjunto de resultados:
-----------------18
(1 row(s) affected)

COUNT(*) se puede combinar con otras funciones de agregado. Esta consulta muestra
COUNT(*) combinado con una funcin AVG en la que ambas funciones de agregado slo
agregan los datos de las filas que cumplen la condicin de bsqueda de la clusula
WHERE.
USE pubs
SELECT COUNT(*), AVG(price)
FROM titles
WHERE advance > $1000
El siguiente es el conjunto de resultados:
----------- -----15
14.42

DISTINCT
La palabra clave DISTINCT es opcional con SUM, AVG y COUNT. Cuando se usa
DISTINCT, los valores duplicados se eliminan antes de que se calcule la suma, el
promedio o el recuento.
Si usa DISTINCT, la expresin slo debe constar del nombre de una columna. No puede
incluir una expresin aritmtica.
En la consulta siguiente se devuelven los precios promedio de los libros de empresa (sin
los valores duplicados).
USE pubs
SELECT AVG(DISTINCT price)
FROM titles
WHERE type = 'business'

www.templatesclarion.com.ar

60

Curso SQL + Clarion - www.templatesclarion.com.ar

El siguiente es el conjunto de resultados:


-----------------14.64
(1 row(s) affected)

Sin DISTINCT, la funcin AVG busca el precio promedio de todos los ttulos de empresa.
USE pubs
SELECT AVG(price)
FROM titles
WHERE type = 'business
El siguiente es el conjunto de resultados:
-----------------13.73
(1 row(s) affected)

1.3.8.2

Agrupar filas con GROUP BY


La clusula GROUP BY se usa para producir valores de agregado para cada fila del
conjunto de resultados. Cuando se usan sin una clusula GROUP BY, las funciones de
agregado slo devuelven un valor de agregado para la instruccin SELECT.
En este ejemplo se devuelve el nmero de unidades vendidas de cada producto de la
categora 2:
USE Northwind
SELECT OrdD.ProductID AS ProdID,
SUM(OrdD.Quantity) AS AmountSold
FROM [Order Details] AS OrdD JOIN Products as Prd
ON OrdD.ProductID = Prd.ProductID
AND Prd.CategoryID = 2
GROUP BY OrdD.ProductID
El siguiente es el conjunto de resultados:
ProdID
----------3
4
5
6
8
15
44
61
63
65
66
77

AmountSold
----------328
453
298
301
372
122
601
603
445
745
239
791

(12 row(s) affected)

A continuacin de las palabras clave GROUP BY se coloca una lista de columnas,


www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

61

conocidas como las columnas de agrupamiento. La clusula GROUP BY restringe las filas
del conjunto de resultados; slo hay una fila por cada valor distinto de la columna o
columnas de agrupamiento. Cada fila del conjunto de resultados contiene los datos de
resumen relacionados con el valor especfico de sus columnas de agrupamiento.

GROUP BY y la clusula WHERE


Puede usar una clusula WHERE en una consulta que contenga una clusula GROUP BY.
Las filas que no cumplan las condiciones de la clusula WHERE son eliminadas antes de
que se realice el agrupamiento. Por ejemplo:
USE pubs
SELECT type, AVG(price)
FROM titles
WHERE advance > $5000
GROUP BY type
El siguiente es el conjunto de resultados:
type
-----------business
mod_cook
popular_comp
psychology
trad_cook

-------------------------2.99
2.99
21.48
14.30
17.97

(5 row(s) affected)

Slo las filas con adelantos superiores a 5.000 dlares se incluyen en los grupos que se
muestran en los resultados de la consulta.

Elegir filas con la clusula HAVING


La clusula HAVING establece las condiciones de la clusula GROUP BY de la misma
forma que WHERE interacta con SELECT. Mientras que las condiciones de bsqueda de
WHERE se aplican antes de que se produzca la operacin de agrupamiento, las
condiciones de bsqueda de HAVING se aplican despus. La sintaxis de la clusula
HAVING es similar a la de la clusula WHERE, con la diferencia de que HAVING puede
contener funciones de agregado. Las clusulas HAVING pueden hacer referencia a
cualquiera de los elementos que aparecen en la lista de seleccin.
En esta consulta se buscan publicadores cuyas ventas anuales hasta la fecha hayan sido
superiores a 40.000 dlares.
USE pubs
SELECT pub_id, total = SUM(ytd_sales)
FROM titles
GROUP BY pub_id
HAVING SUM(ytd_sales) > 40000
El siguiente es el conjunto de resultados:
pub_id total
------ ----------0877
44219
(1 row(s) affected)

www.templatesclarion.com.ar

62

Curso SQL + Clarion - www.templatesclarion.com.ar

Para asegurarse de que hay como mnimo seis libros involucrados en los clculos para
cada publicador, este ejemplo utiliza HAVING COUNT(*) > 5 para eliminar los
publicadores que devuelven totales con menos de seis libros.
USE pubs
SELECT pub_id, total = SUM(ytd_sales)
FROM titles
GROUP BY pub_id
HAVING COUNT(*) > 5
El siguiente es el conjunto de resultados:
pub_id
-----0877
1389

total
----------44219
24941

(2 row(s) affected)

La comprensin de la secuencia correcta en la que se aplican las clusulas WHERE,


GROUP BY y HAVING ayuda a codificar consultas que sean eficientes:
La clusula WHERE se utiliza para filtrar las filas que resultan de las operaciones
especificadas en la clusula FROM.

La clusula GROUP BY se usa para agrupar el resultado de la clusula WHERE.

La clusula HAVING se usa para filtrar las filas del resultado agrupado.
Es ms eficiente especificar en la clusula WHERE las condiciones de bsqueda que se
pueden establecer antes o despus de la operacin de agrupamiento. Esto reduce el
nmero de filas que tienen que agruparse. Las nicas condiciones de bsqueda que se
deben especificar en la clusula HAVING son aquellas que se deben aplicar una vez que
se hayan realizado las operaciones de agrupamiento.
El optimizador de consultas de Microsoft SQL Server 2000 puede tratar la mayor
parte de estas condiciones. Si el optimizador determina que una condicin de bsqueda
HAVING se puede aplicar antes de la operacin de agrupamiento, lo har. Puede que el
optimizador no reconozca todas las condiciones de bsqueda de HAVING que se pueden
aplicar antes de la operacin de agrupamiento. Se recomienda colocar todas estas
condiciones de bsqueda en la clusula WHERE en lugar de en la clusula HAVING.
En la consulta siguiente se muestra la clusula HAVING con una funcin de agregado.
Agrupa por tipos las filas de la tabla titles y elimina los grupos que incluyen solamente
un libro:
USE pubs
SELECT type
FROM titles
GROUP BY type
HAVING COUNT(*) > 1
El siguiente es el conjunto de resultados:

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

63

type
-----------------business
mod_cook
popular_comp
psychology
trad_cook
(5 row(s) affected)

Cuando en HAVING se incluyen varias condiciones, se combinan mediante AND, OR o


NOT. En el ejemplo siguiente se muestra cmo agrupar titles por publicadores,
incluyendo slo aquellos cuyo nmero de identificacin sea superior a 0800, hayan
pagado ms de 15.000 dlares en adelantos totales y vendan libros por un promedio de
menos de 20 dlares.
SELECT pub_id, SUM(advance) AS AmountAdvanced,
AVG(price) AS AveragePrice
FROM pubs.dbo.titles
WHERE pub_id > '0800'
GROUP BY pub_id
HAVING SUM(advance) > $15000
AND AVG(price) < $20
ORDER BY se puede usar para ordenar el resultado de una clusula GROUP BY. En este
ejemplo se muestra la utilizacin de la clusula ORDER BY para definir el orden en el que
se devuelven las filas de una clusula GROUP BY:
SELECT pub_id, SUM(advance) AS AmountAdvanced,
AVG(price) AS AveragePrice
FROM pubs.dbo.titles
WHERE pub_id > '0800'
AND price >= $5
GROUP BY pub_id
HAVING SUM(advance) > $15000
AND AVG(price) < $20
ORDER BY pub_id DESC

1.3.8.3

Combinar resultados con UNION


El operador UNION permite combinar los resultados de varias instrucciones SELECT en
un nico conjunto de resultados. Todos los conjuntos de resultados combinados mediante
UNION deben tener la misma estructura.
Deben tener el mismo nmero de columnas y las columnas del conjunto de resultados
correspondientes deben tener tipos de datos compatibles

Instrucciones para utilizar UNION


Cuando utilice operadores UNION, siga estas directrices:
Todas las listas de seleccin de las instrucciones que se combinan con UNION deben
tener el mismo nmero de expresiones (nombres de columna, expresiones aritmticas,
funciones de agregado, etc.).
www.templatesclarion.com.ar

64

Curso SQL + Clarion - www.templatesclarion.com.ar

Las columnas correspondientes del conjunto de resultados combinado con UNION, o


cualquier subconjunto de columnas que se use en consultas individuales, deben ser del
mismo tipo de datos, tener la posibilidad de convertir los tipos de datos de forma
implcita o suministrar una conversin explcita. Por ejemplo, no es posible utilizar
UNION entre una columna de un tipo de datos datetime y una de tipo de datos binary,
a menos que se suministre una conversin explcita, mientras s que se puede aplicar
UNION entre una columna de tipo de datos money y una del tipo int porque pueden
convertirse implcitamente.
Las columnas del conjunto de resultados de las instrucciones individuales que se
combinan con UNION deben estar en el mismo orden, porque UNION compara las
columnas de una en una en el orden que se indica en las consultas individuales.

1.3.9

Subconsultas
Una subconsulta es una consulta SELECT que devuelve un valor nico y est anidada en
una instruccin SELECT, INSERT, UPDATE o DELETE, o dentro de otra subconsulta. Una
subconsulta se puede utilizar en cualquier parte en la que se permita una expresin. En
este ejemplo se utiliza una subconsulta como una expresin de columna llamada
MaxUnitPrice en una instruccin SELECT.
SELECT Ord.OrderID, Ord.OrderDate,
(SELECT MAX(OrdDet.UnitPrice)
FROM Northwind.dbo.[Order Details] AS OrdDet
WHERE Ord.OrderID = OrdDet.OrderID) AS MaxUnitPrice
FROM Northwind.dbo.Orders AS Ord
Se llama tambin subconsulta a una consulta o seleccin interna, mientras que la
instruccin que contiene una subconsulta tambin es conocida como consulta o seleccin
externa.
Muchas de las instrucciones Transact-SQL que incluyen subconsultas se pueden formular
tambin como combinaciones. Otras preguntas se pueden formular slo con
subconsultas. En Transact-SQL, normalmente no hay diferencias de rendimiento entre
una instruccin que incluya una subconsulta y una versin semnticamente equivalente
que no lo haga. Sin embargo, en algunos casos en los que se debe comprobar la
existencia de algo, una combinacin produce mejores resultados. De lo contrario, la
consulta anidada debe ser procesada para cada resultado de la consulta externa con el
fin de asegurar la eliminacin de los duplicados. En tales casos, la utilizacin de
combinaciones producira los mejores resultados. Esto es un ejemplo que muestra una
subconsulta SELECT y una combinacin SELECT que devuelve el mismo conjunto de
resultados:
/* SELECT statement built using a subquery. */

SELECT ProductName
FROM Northwind.dbo.Products
WHERE UnitPrice =
(SELECT UnitPrice
FROM Northwind.dbo.Products
WHERE ProductName = 'Sir Rodney''s Scones')
/* SELECT statement built using a join that returns
the same result set. */

SELECT Prd1.ProductName
FROM Northwind.dbo.Products AS Prd1
JOIN Northwind.dbo.Products AS Prd2

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

65

ON (Prd1.UnitPrice = Prd2.UnitPrice)
WHERE Prd2.ProductName = 'Sir Rodney''s Scones'
La consulta SELECT de una subconsulta se incluye siempre entre parntesis. No puede
incluir una clusula COMPUTE o FOR BROWSE y slo puede incluir una clusula ORDER
BY cuando se especifica tambin una clusula TOP.
Una subconsulta puede anidarse dentro de la clusula WHERE o HAVING de una
instruccin externa SELECT, INSERT, UPDATE o DELETE, o dentro de otra subconsulta. Se
puede disponer de hasta 32 niveles de anidamiento, aunque el lmite vara dependiendo
de la memoria disponible y de la complejidad del resto de las expresiones de la consulta.
Las consultas individuales puede que no admitan anidamientos por encima de 32 niveles.
Una subconsulta puede aparecer en cualquier parte en la que se pueda usar una
expresin, si devuelve un valor individual.
Si una tabla aparece slo en una subconsulta y no en la consulta externa, las columnas
de esa tabla no se pueden incluir en el resultado (la lista de seleccin de la consulta
externa).

Tipos de Subconsultas
Las instrucciones que incluyen una subconsulta normalmente tienen uno de estos
formatos:
WHERE expression [NOT] IN (subquery)
WHERE expression comparison_operator [ANY | ALL] (subquery)
WHERE [NOT] EXISTS (subquery)
Hay tres tipos bsicos de subconsultas:
Operan en listas incorporadas con IN, o en aqullas que modific un operador de
comparacin mediante ANY o ALL.
Se introducen con un operador de comparacin sin modificar y deben devolver un valor
individual.
Son pruebas de existencia que se introducen con EXISTS.

Reglas de las subconsultas


Una subconsulta est sujeta a una serie de limitaciones:
La lista de seleccin de una subconsulta presentada con un operador de comparacin
slo puede incluir una expresin o nombre de columna (excepto EXISTS e IN, que
operan en SELECT * o en una lista, respectivamente).
Si la clusula WHERE de una consulta externa incluye un nombre de columna, debe ser
compatible en cuanto a combinacin con la columna nombrada en la lista de seleccin
de la subconsulta.
Los tipos de datos ntext, text e image no estn permitidos en las listas de seleccin de
subconsultas.
Puesto que deben devolver un valor individual, las subconsultas presentadas por un
operador de comparacin sin modificar (uno no seguido de la palabra clave ANY o ALL)
no pueden incluir clusulas GROUP BY y HAVING.
La palabra clave DISTINCT no se puede usar con subconsultas que incluyan GROUP BY.
No se pueden especificar las clusulas COMPUTE e INTO.
Slo se puede especificar ORDER BY si se especifica tambin TOP.
Una vista creada con una subconsulta no se puede actualizar.
La lista de seleccin de una subconsulta presentada con EXISTS consta, por
convencin, de un asterisco (*) en lugar de un nombre de columna individual. Las

www.templatesclarion.com.ar

66

Curso SQL + Clarion - www.templatesclarion.com.ar

reglas de una subconsulta presentada con EXISTS son idnticas a las de una lista de
seleccin estndar porque una subconsulta presentada con EXISTS constituye una
prueba de existencia y devuelve TRUE o FALSE en lugar de datos.

Temas Relacionados:
Subconsultas con Alias
Subconsultas con IN
Subconsultas con NOT IN
Subconsultas en UPDATE, DELETE e INSERT
Subconsultas con operadores de comparacin
Subconsultas con EXISTS
Subconsultas con NOT EXISTS
Subconsultas usadas en lugar de una expresin
Mltiples niveles de anidamiento
Procesamiento condicional con CASE
1.3.9.1

Subconsultas con Alias


Muchas instrucciones en las que la subconsulta y la consulta externa hacen referencia a
la misma tabla se pueden indicar como autocombinaciones (combinar una tabla con ella
misma). Por ejemplo, si usa una subconsulta, puede buscar autores que viven en la
misma ciudad que Livia Karsen:
USE pubs
SELECT au_lname, au_fname, city
FROM authors
WHERE city IN
(SELECT city
FROM authors
WHERE au_fname = 'Livia'
AND au_lname = 'Karsen')
El siguiente es el conjunto de resultados:
au_lname
---------------------------------------Green
Straight
Stringer
MacFeather
Karsen

au_fname
-------------------Marjorie
Dean
Dirk
Stearns
Livia

city
---------Oakland
Oakland
Oakland
Oakland
Oakland

(5 row(s) affected)

O bien, puede usar una autocombinacin:


USE pubs
SELECT au1.au_lname, au1.au_fname, au1.city
FROM authors AS au1 INNER JOIN authors AS au2 ON au1.city = au2.city
AND au2.au_lname = 'Karsen'
AND au2.au_fname = 'Livia'
Los alias de tabla son necesarios porque la tabla que se est combinando consigo misma
aparece en dos funciones distintas. Los alias se pueden usar tambin en las consultas
anidadas que hacen referencia a la misma tabla en una consulta interna y externa.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

67

USE pubs
SELECT au1.au_lname, au1.au_fname, au1.city
FROM authors AS au1
WHERE au1.city in
(SELECT au2.city
FROM authors AS au2
WHERE au2.au_fname = 'Livia'
AND au2.au_lname = 'Karsen')
Los alias explcitos indican claramente que las referencias a authors de la subconsulta no
significan lo mismo que las referencias de la consulta externa.
1.3.9.2

Subconsultas con IN
El resultado de una subconsulta presentada con IN (o con NOT IN) es una lista de cero o
ms valores. Una vez que la consulta devuelve los resultados, la consulta externa hace
uso de ellos.
En esta consulta se buscan los nombres de los editores que han publicado libros de
empresa.
USE pubs
SELECT pub_name
FROM publishers
WHERE pub_id IN
(SELECT pub_id
FROM titles
WHERE type = 'business')
El siguiente es el conjunto de resultados:
pub_name
---------------------------------------Algodata Infosystems
New Moon Books
(2 row(s) affected)

Esta instruccin se evala en dos pasos. Primero, la consulta interna devuelve los
nmeros de identificacin de los editores que han publicado libros de empresa (1389 y
0736). Segundo, estos valores se sustituyen en la consulta externa, que busca los
nombres asociados con los nmeros de identificacin en publishers.
USE pubs
SELECT pub_name
FROM publishers
WHERE pub_id in ('1389', '0736')
Una diferencia de la utilizacin de una combinacin en lugar de una subconsulta, para
este problema y otros similares, es que la combinacin permite mostrar, en el resultado,
columnas de ms de una tabla. Por ejemplo, si desea incluir en el resultado el ttulo de
los libros de empresa, debe usar combinaciones.
USE pubs
SELECT pub_name, title

www.templatesclarion.com.ar

68

Curso SQL + Clarion - www.templatesclarion.com.ar

FROM publishers INNER JOIN titles ON publishers.pub_id = titles.pub_id


AND type = 'business'
El siguiente es el conjunto de resultados:
pub_name
---------------------Algodata Infosystems
Algodata Infosystems

title
------------------------------------------------The Busy Executive's Database Guide
Cooking with Computers: Surreptitious Balance Sheets

New Moon Books


Algodata Infosystems

You Can Combat Computer Stress!


Straight Talk About Computers

(4 row(s) affected)

Esta consulta muestra que la combinacin produce cuatro filas, no dos como en la
subconsulta anterior.
Este es otro ejemplo de una consulta que se puede formular con una subconsulta o con
una combinacin. Esta consulta busca los nombres de todos los segundos autores que
viven en California y que reciben menos del 30 por ciento de los derechos de autor de un
libro.
USE pubs
SELECT au_lname, au_fname
FROM authors
WHERE state = 'CA'
AND au_id IN
(SELECT au_id
FROM titleauthor
WHERE royaltyper < 30
AND au_ord = 2)
El siguiente es el conjunto de resultados:
El siguiente es el conjunto de resultados:
au_lname
au_fname
---------------------------------------- -------------------MacFeather
Stearns
(1 row(s) affected)

Se evala la consulta interna y da como resultado los nmeros de Id. de los tres autores
que cumplen las calificaciones de la subconsulta. Despus se evala la consulta externa.
Observe que puede incluir ms de una condicin en la clusula WHERE tanto de las
consultas internas como de las externas.
Mediante una combinacin, la misma consulta se expresa de esta forma:
USE pubs
SELECT au_lname, au_fname
FROM authors INNER JOIN titleauthor ON authors.au_id = titleauthor.au_id
WHERE state = 'CA'
AND royaltyper < 30
AND au_ord = 2
Una combinacin se puede expresar siempre como una subconsulta. Una subconsulta se

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

69

puede expresar a menudo, aunque no siempre, como una combinacin. Esto se debe a
que las combinaciones son simtricas: puede combinar las tablas A y B en cualquier
orden y obtener la misma respuesta. Lo mismo no es cierto si se implica a una
subconsulta.
1.3.9.3

Subconsultas con NOT IN


Las subconsultas presentadas con la palabra clave NOT IN devuelven tambin una lista
de cero o ms valores.
Esta consulta busca los nombres de los editores que no han publicado libros de empresa.
USE pubs
SELECT pub_name
FROM publishers
WHERE pub_id NOT IN
(SELECT pub_id
FROM titles
WHERE type = 'business')
La consulta es exactamente la misma que la de las subconsultas con IN, excepto en que
NOT IN se sustituye por IN. Sin embargo, esta instruccin no se puede convertir a una
combinacin. La combinacin anloga "no igual" tiene un significado distinto: busca los
nombres de los editores que han publicado algn libro que no sea de empresa.

1.3.9.4

Subconsultas en UPDATE, DELETE e INSERT


Las subconsultas se pueden anidar en las instrucciones UPDATE, DELETE e INSERT, as
como en las instrucciones SELECT.
La siguiente consulta dobla el precio de todos los libros publicados por New Moon Books.
La consulta actualiza la tabla titles; su subconsulta hace referencia a la tabla publishers.
UPDATE titles
SET price = price * 2
WHERE pub_id IN
(SELECT pub_id
FROM publishers
WHERE pub_name = 'New Moon Books')
sta es una instruccin UPDATE equivalente que usa una combinacin:
UPDATE titles
SET price = price * 2
FROM titles INNER JOIN publishers ON titles.pub_id = publishers.pub_id
AND pub_name = 'New Moon Books'
Puede quitar todos los registros de ventas de los libros de empresa con esta consulta
anidada:
DELETE sales
WHERE title_id IN
(SELECT title_id
FROM titles
WHERE type = 'business')

www.templatesclarion.com.ar

70

Curso SQL + Clarion - www.templatesclarion.com.ar

sta es una instruccin DELETE equivalente que usa una combinacin:


DELETE sales
FROM sales INNER JOIN titles ON sales.title_id = titles.title_id
AND type = 'business'
1.3.9.5

Subconsultas con operadores de comparacin


Las subconsultas se pueden presentar con uno de los operadores de comparacin (=, <
>, >, > =, <, ! >, ! < o < =).
Una subconsulta presentada con un operador de comparacin sin modificar (un operador
de comparacin no seguido de ANY o ALL) debe devolver un valor individual en lugar de
una lista de valores, como las subconsultas presentadas con IN. Si tal subconsulta
devuelve ms de un valor, Microsoft SQL Server muestra un mensaje de error.
Para usar una subconsulta presentada con un operador de comparacin sin modificar,
debe estar suficientemente familiarizado con los datos y con la naturaleza del problema
para saber que la subconsulta devolver exactamente un valor.
Por ejemplo, si supone que cada editor se encuentra en una sola ciudad, y desea
encontrar el nombre de los autores que viven en la ciudad en la que se encuentra
Algodata Infosystems, puede escribir una instruccin con una subconsulta presentada
con el operador de comparacin simple =.
USE pubs
SELECT au_lname, au_fname
FROM authors
WHERE city =
(SELECT city
FROM publishers
WHERE pub_name = 'Algodata Infosystems')
El siguiente es el conjunto de resultados:
au_lname
-------Carson
Bennet

au_fname
-------Cheryl
Abraham

(2 row(s) affected)

Sin embargo, si Algodata Infosystems estuviera ubicada en varias ciudades, se producira


un mensaje de error. En lugar del operador de comparacin =, se podra usar una
formulacin IN (= ANY funciona tambin).
Las subconsultas presentadas con operadores de comparacin sin modificar incluyen, a
menudo, funciones agregadas, puesto que stas devuelven un valor individual. Por
ejemplo, esta instruccin busca los nombres de todos los libros con un precio superior al
precio actual mnimo.
USE pubs
SELECT DISTINCT title
FROM titles

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

71

WHERE price >


(SELECT MIN(price)
FROM titles)
El siguiente es el conjunto de resultados:
title
---------------------------------------------------------But Is It User Friendly?
Computer Phobic and Non-Phobic Individuals: Behavior Variations
Cooking with Computers: Surreptitious Balance Sheets
Emotional Security: A New Algorithm
Fifty Years in Buckingham Palace Kitchens
Is Anger the Enemy?
Life Without Fear
Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean
Prolonged Data Deprivation: Four Case Studies
Secrets of Silicon Valley
Silicon Valley Gastronomic Treats
Straight Talk About Computers
Sushi, Anyone?
The Busy Executive's Database Guide
(14 row(s) affected)

Puesto que las subconsultas presentadas con operadores de comparacin sin modificar
deben devolver un valor individual, no pueden incluir clusulas GROUP BY o HAVING a
menos que sepa que la propia clusula GROUP BY o HAVING devuelve un valor
individual. Por ejemplo, esta consulta busca los libros con un precio superior al del libro
con el menor precio que sea del tipo 'trad_cook'.
USE pubs
SELECT DISTINCT title
FROM titles
WHERE price >
(SELECT MIN(price)
FROM titles
GROUP BY type
HAVING type = 'trad_cook')
El siguiente es el conjunto de resultados:
title
-----------------------------------------------------------------------But Is It User Friendly?
Computer Phobic AND Non-Phobic Individuals: Behavior Variations
Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean
Prolonged Data Deprivation: Four Case Studies
Secrets of Silicon Valley
Silicon Valley Gastronomic Treats
Straight Talk About Computers
Sushi, Anyone?
The Busy Executive's Database Guide
(9 row(s) affected)

www.templatesclarion.com.ar

72

1.3.9.6

Curso SQL + Clarion - www.templatesclarion.com.ar

Subconsultas con EXISTS


Cuando se presenta una subconsulta con la palabra clave EXISTS, funciona como una
prueba de existencia. La clusula WHERE de la consulta externa comprueba la existencia
de las filas devueltas por la subconsulta. La subconsulta en realidad no produce ningn
dato, devuelve el valor TRUE o FALSE.
Una subconsulta presentada con EXISTS tiene la siguiente sintaxis:
WHERE [NOT] EXISTS (subquery)
En esta consulta se busca el nombre de todos los editores que publican libros de
empresa.
USE pubs
SELECT pub_name
FROM publishers
WHERE EXISTS
(SELECT *
FROM titles
WHERE pub_id = publishers.pub_id
AND type = 'business')
El siguiente es el conjunto de resultados:
pub_name
-------------------New Moon Books
Algodata Infosystems
(2 row(s) affected)

Para determinar los resultados de esta consulta, considere el nombre de cada editor de
uno en uno. Este valor hace que la subconsulta devuelva una fila, como mnimo? En
otras palabras, hace que la prueba de existencia d como resultado TRUE?
En este caso, el primer nombre de editor es Algodata Infosystems, con nmero de
identificacin 1389. Hay filas en la tabla titles cuyo pub_id sea 1389 y cuyo type sea
empresa? Si lo hay, Algodata Infosystems debe ser uno de los valores seleccionados. El
mismo proceso se repite para cada uno de los restantes nombres de editor.
Observe que las subconsultas presentadas con EXISTS son ligeramente distintas de las
restantes subconsultas en los aspectos siguientes:
La palabra clave EXISTS no se precede de un nombre de columna, constante u otra
expresin.

La lista de seleccin de una subconsulta presentada por EXISTS casi siempre consta de
un asterisco (*). No hay razn para enumerar los nombres de las columnas porque
simplemente se est comprobando la existencia de filas que cumplan las condiciones
especificadas en la subconsulta.
La palabra clave EXISTS es importante porque a veces no hay una formulacin
alternativa de la subconsulta. Aunque algunas consultas formuladas con EXISTS no se
pueden expresar de ninguna otra forma, todas las consultas que usan IN o un operador

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

73

de comparacin modificado por ANY o ALL se pueden expresar con EXISTS.


A continuacin se muestran algunos ejemplos de consultas que usan EXISTS y sus
alternativas equivalentes.
Se muestran dos formas de buscar autores que vivan en la misma ciudad que un editor:
USE pubs
SELECT au_lname, au_fname
FROM authors
WHERE city =ANY
(SELECT city
FROM publishers)
-- Or
USE pubs
SELECT au_lname, au_fname
FROM authors
WHERE exists
(SELECT *
FROM publishers
WHERE authors.city = publishers.city)
ste es el conjunto de resultados de las consultas:
au_lname
-------Carson
Bennet

au_fname
-------Cheryl
Abraham

(2 row(s) affected)

Estas dos consultas buscan ttulos de libros publicados por algn editor que se encuentre
en una ciudad que comience con la letra B.
USE pubs
SELECT title
FROM titles
WHERE pub_id IN
(SELECT pub_id
FROM publishers
WHERE city LIKE 'B%')
-- Or
USE pubs
SELECT title
FROM titles
WHERE EXISTS
(SELECT *
FROM publishers
WHERE pub_id = titles.pub_id
AND city LIKE 'B%')
ste es el conjunto de resultados de las consultas:
title
---------------------------------------------------The Busy Executive's Database Guide
Cooking with Computers: Surreptitious Balance Sheets
You Can Combat Computer Stress!
Straight Talk About Computers

www.templatesclarion.com.ar

74

Curso SQL + Clarion - www.templatesclarion.com.ar

But Is It User Friendly?


Secrets of Silicon Valley
Net Etiquette
Is Anger the Enemy?
Life Without Fear
Prolonged Data Deprivation: Four Case Studies
Emotional Security: A New Algorithm
(11 row(s) affected)

1.3.9.7

Subconsultas con NOT EXISTS


NOT EXISTS funciona igual que EXISTS, salvo por el hecho de que la clusula WHERE en
la que se utiliza se cumple si la subconsulta no devuelve ninguna fila.
En el ejemplo siguiente se buscan nombres de editores que no publiquen libros de
empresa:
USE pubs
SELECT pub_name
FROM publishers
WHERE NOT EXISTS
(SELECT *
FROM titles
WHERE pub_id = publishers.pub_id
AND type = 'business')
El siguiente es el conjunto de resultados:
pub_name
---------------------------------------Binnet & Hardley
Five Lakes Publishing
Ramona Publishers
GGG&G
Scootney Books
Lucerne Publishing
(6 row(s) affected)

En esta consulta se buscan los ttulos de los que no ha habido ninguna venta.
USE pubs
SELECT title
FROM titles
WHERE NOT EXISTS
(SELECT title_id
FROM sales
WHERE title_id = titles.title_id)
El siguiente es el conjunto de resultados:
title
---------------------------------The Psychology of Computer Cooking
Net Etiquette
(2 row(s) affected)

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

1.3.9.8

75

Subconsultas usadas en lugar de una expresin


En Transact-SQL, una subconsulta se puede usar all donde se pueda usar una expresin
en las instrucciones SELECT, UPDATE, INSERT y DELETE, excepto en una lista ORDER BY.
El siguiente ejemplo muestra cmo podra usar esta mejora. Esta consulta busca el
precio de un libro conocido de informtica, el promedio de todos los libros y la diferencia
entre el precio del libro y el precio promedio de todos los libros.
USE pubs
SELECT title, price,
(SELECT AVG(price) FROM titles) AS average,
price-(SELECT AVG(price) FROM titles) AS difference
FROM titles
WHERE type='popular_comp'
El siguiente es el conjunto de resultados:
title
-----------------------But Is It User Friendly?
Secrets of Silicon Valley
Net Etiquette

price
-------------22.95
20.00
(null)

average
-------------14.77
14.77
14.77

difference
---------------8.18
5.23
(null)

(3 row(s) affected)

1.3.9.9

Mltiples niveles de anidamiento


Una subconsulta puede incluir en s una o varias subconsultas. En una instruccin se
puede anidar cualquier nmero de subconsultas.
Esta consulta busca el nombre de los autores que han participado en la escritura de,
como mnimo, un libro conocido de informtica.
USE pubs
SELECT au_lname, au_fname
FROM authors
WHERE au_id IN
(SELECT au_id
FROM titleauthor
WHERE title_id IN
(SELECT title_id
FROM titles
WHERE type = 'popular_comp'))
El siguiente es el conjunto de resultados:
au_lname
---------------------------------------Carson
Dull
Locksley
Hunter

au_fname
-------------------Cheryl
Ann
Charlene
Sheryl

(4 row(s) affected)

La consulta ms interna devuelve los nmeros de Id. de ttulo PC1035, PC8888 y


PC9999. La consulta del siguiente nivel superior se evala con estos Id. de ttulo y
devuelve los nmeros de Id. del autor. Finalmente, la consulta externa usa los Id. de

www.templatesclarion.com.ar

76

Curso SQL + Clarion - www.templatesclarion.com.ar

autor para buscar el nombre de los autores.


Tambin puede expresar esta consulta como una combinacin:
USE pubs
SELECT au_lname, au_fname
FROM authors INNER JOIN titleauthor ON authors.au_id = titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id
WHERE type = 'popular_comp'
1.3.9.10 Procesamiento condicional con CASE
La funcin CASE se utiliza para evaluar varias condiciones y devolver un valor nico para
cada condicin. Una utilizacin normal de la funcin CASE es sustituir cdigos o
abreviaturas por valores ms legibles. En la siguiente consulta se usa la funcin CASE
para cambiar el nombre a las categoras de libros, de forma que sean ms
comprensibles.
USE pubs
SELECT
CASE type
WHEN 'popular_comp' THEN 'Popular Computing'
WHEN 'mod_cook' THEN 'Modern Cooking'
WHEN 'business' THEN 'Business'
WHEN 'psychology' THEN 'Psychology'
WHEN 'trad_cook' THEN 'Traditional Cooking'
ELSE 'Not yet categorized'
END AS Category,
CONVERT(varchar(30), title) AS "Shortened Title",
price AS Price
FROM titles
WHERE price IS NOT NULL
ORDER BY 1
El siguiente es el conjunto de resultados:
category
------------------Business
Business
Business
Business
Modern Cooking
Modern Cooking
Popular Computing
Popular Computing
Psychology
Psychology
Psychology
Psychology
Psychology
Traditional Cooking
Traditional Cooking
Traditional Cooking

shortened title
-----------------------------Cooking with Computers: Surrep
Straight Talk About Computers
The Busy Executive's Database
You Can Combat Computer Stress
Silicon Valley Gastronomic Tre
The Gourmet Microwave
But Is It User Friendly?
Secrets of Silicon Valley
Computer Phobic AND Non-Phobic
Emotional Security: A New Algo
Is Anger the Enemy?
Life Without Fear
Prolonged Data Deprivation: Fo
Fifty Years in Buckingham Pala
Onions, Leeks, and Garlic: Coo
Sushi, Anyone?

Price
------11.95
19.99
19.99
2.99
19.99
2.99
22.95
20.00
21.59
7.99
10.95
7.00
19.99
11.95
20.95
14.99

(16 row(s) affected)

CASE tambin se utiliza para clasificar datos. La siguiente consulta utiliza la funcin

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

77

CASE para clasificar precios.


SELECT
CASE
WHEN price IS NULL THEN 'Not yet priced'
WHEN price < 10 THEN 'Very Reasonable Title'
WHEN price >= 10 and price < 20 THEN 'Coffee Table Title'
ELSE 'Expensive book!'
END AS "Price Category",
CONVERT(varchar(20), title) AS "Shortened Title"
FROM pubs.dbo.titles
ORDER BY price
El siguiente es el conjunto de resultados:
Price Category
--------------------Not yet priced
Not yet priced
Very Reasonable Title
Very Reasonable Title
Very Reasonable Title
Very Reasonable Title
Coffee Table Title
Coffee Table Title
Coffee Table Title
Coffee Table Title
Coffee Table Title
Coffee Table Title
Coffee Table Title
Coffee Table Title
Expensive book!
Expensive book!
Expensive book!
Expensive book!

Shortened Title
-------------------The Psychology of Co
Net Etiquette
You Can Combat Compu
The Gourmet Microwav
Life Without Fear
Emotional Security:
Is Anger the Enemy?
Cooking with Compute
Fifty Years in Bucki
Sushi, Anyone?
The Busy Executive's
Straight Talk About
Silicon Valley Gastr
Prolonged Data Depri
Secrets of Silicon V
Onions, Leeks, and G
Computer Phobic AND
But Is It User Frien

(18 row(s) affected)

1.3.10 Transacciones y control de la concurrencia


Los motores SQL son sistemas concurrentes, o sea que admiten la ejecucin concurrente
de consultas. Ejemplo: Sistema de venta de boletos de avin.
Por tanto, son necesarios modelos de procesos concurrentes para admitir operaciones
concurrentes que preserven la integridad de los datos.

Transaccin
Una transaccin es una unidad de la ejecucin de un programa. Puede consistir en varias
operaciones de acceso a la base de datos. Est delimitada por comandos que indican el
inicio, el fin exitoso o la cancelacion de la misma.

Propiedades A.C.I.D.
Atomicidad
Es la propiedad de las transacciones que permite observarlas como operaciones
atmicas: ocurren totalmente o no ocurren.

www.templatesclarion.com.ar

78

Curso SQL + Clarion - www.templatesclarion.com.ar

Consistencia
La ejecucin aislada de la transaccin conserva la consistencia de la base de datos.

Aislamiento (Isolation)
Para cada par de transacciones que puedan ejecutarse concurrentemente Ti y Tj, se
cumple que para los efectos de Ti:
- Tj ha terminado antes de que comience Ti
- Tj ha comenzado despus de que termine Ti
Las transacciones son independientes entre s.

Niveles de aislamiento
Se puede ajustar el nivel de aislamiento entre las transacciones y determina para una
transaccin el grado de aceptacin de datos inconsistentes.
A mayor grado de aislamiento, mayor precisin, pero a costa de menor concurrencia.
El nivel de aislamiento para una sesin SQL establece el comportamiento de los bloqueos
para las instrucciones SQL.
Niveles de aislamiento:
Lectura no comprometida. Menor nivel. Asegura que no se lean datos corruptos
fsicamente.
Lectura comprometida. Slo se permiten lecturas de datos comprometidos.
Lectura repetible. Las lecturas repetidas de la misma fila para la misma transaccin
dan los mismos resultados.
Secuenciable. Mayor nivel de aislamiento. Las transacciones se aslan completamente.

Comportamiento concurrente de las transacciones.


Lectura sucia. Lectura de datos no comprometidos. (Retrocesos)
Lectura no repetible. Se obtienen resultados inconsistentes en lecturas repetidas.
Lectura fantasma. Una lectura de una fila que no exista cuando se inici la
transaccin.

Nivel de
aislamiento

Lectura
sucia

Lectura no
repetible

Lectura
fantasma

Lectura no
comprometida

Lectura
comprometida

No

Lectura repetible

No

No

Secuenciable

No

No

No

SQL Server permite todos estos niveles, Oracle slo permite la lectura comprometida y
secuenciable. Los niveles se pueden establecer en ambos para cada transaccin.

Durabilidad
El sistema gestor de bases de datos asegura que los cambios realizados por una
transaccin que termina con xito perduran.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

79

Estados de una transaccin

Activa: Durante su ejecucin


Parcialmente comprometida: Despus de ejecutar su ltima instruccin.
Fallida: Imposible de continuar su ejecucin normal.
Abortada: Transaccin retrocedida y base de datos restaurada al estado anterior a su
ejecucin. Se puede reiniciar o cancelar.

Transacciones anidadas
Una transaccin anidada o multinivel T consiste en un conjunto T = {t1, t2, . . ., tn} de
subtransacciones y en un orden parcial P sobre T.
Cada ti de T puede abortar sin obligar a que T aborte. Puede que T reinicie ti o
simplemente no ejecute ti. Si se compromete ti, esa accin no hace que ti sea
permanente, sino que ti se compromete con T, y puede que aborte si T aborta.
La ejecucin de T no debe violar el orden parcial P. Es decir, si aparece un arco ti ? tj en
el grafo de precedencia, tj ? ti no debe estar en el cierre transitivo de P.

Temas Relacionados:
Bloqueos
Read Commited
Read Uncommited
Repeatable Read
Serializable
1.3.10.1 Bloqueos
Un bloqueo es una informacin del tipo de acceso que se permite a un elemento. El
motor SQL impone los bloqueos necesarios en cada momento. El gestor de acceso a los
datos implementa las restricciones de acceso. En algunos sistemas se permite que el
usuario pueda indicar el bloqueo ms adecuado (locking hints).

Tipos de bloqueo con respecto a la operacin


read-locks: slo permite lectura
write-locks: permite lectura y escritura
El gestor de bloqueos almacena los bloqueos en una tabla de bloqueos:
(<elemento>, <tipo de bloqueo>, <transaccin>)=(E,B,T)
La transaccin T tiene un tipo de bloqueo B sobre el elemento E.
Normalmente, E es clave, aunque no siempre, porque varias transacciones pueden
bloquear el mismo elemento de forma diferente.

Niveles de bloqueo
Especifica la granularidad del bloqueo
Fila: Fila individual
Clave: Fila de un ndice
Pgina: Pginas (8KB)
Extent: Extensin (grupo de 8 pginas contiguas de datos o ndices)
Table: Tabla completa
Database: Base de datos completa

Modos de bloqueo
Especifica el modo en que se bloquea un elemento

www.templatesclarion.com.ar

80

Curso SQL + Clarion - www.templatesclarion.com.ar

Compartido: para operaciones slo de lectura. Se permiten lecturas concurrentes, pero


ninguna actualizacin.
Actualizacin: para operaciones que pueden escribir. Slo se permite que una
transaccin adquiera este bloqueo. Si la transaccin modifica datos, se convierte en
exclusivo, en caso contrario en compartido.
Exclusivo. para operaciones que escriben datos. Slo se permite que una transaccin
adquiera este bloqueo.
Intencin: se usan para establecer una jerarqua de bloqueo. Por ejemplo, si una
transaccin necesita bloqueo exclusivo y varias transacciones tienen bloqueo de
intencin, no se concede el exclusivo.
Intencin compartida. Bloqueo compartido.
Intencin exclusiva. Bloqueo exclusivo.
Compartido con intencin exclusivo. Algunos bloqueos compartidos y otros exclusivos.
Esquema. Para operaciones del DDL (modificacion de estructuras de datos).
Actualizacin masiva. En operaciones de actualizacin masiva.

Livelock
Espera indefinida de una transaccin por un bloqueo que no se llega a conceder porque
se cede a otras transacciones.
Una solucin (sistemas operativos): estrategia first-come-first-served (se atiende al
primero que llega).

Deadlock
T1: LOCK A; LOCK B; UNLOCK A; UNLOCK B;
T2: LOCK B; LOCK A; UNLOCK B; UNLOCK A;
T1 y T2 bloquean A y B => Espera indefinida de T1 y T2.
Soluciones (sistemas operativos):
1- Concesin simultnea de todos los bloqueos de una transaccin.
2- Asignar un orden lineal arbitrario a los elementos y requerir que las transacciones
pidan los bloqueos en este orden.
3- Permitir los deadlocks y analizar cada cierto tiempo si existen. Este es el caso del
SQL Server, por lo tanto es nuestra responsabilidad evitar los DeadLocks.
1.3.10.2 Read Uncommited
Lecturas no confirmadas, nivel ms bajo de aislamiento solamente protege de lecturas de
datos fsicamente daados. Es el que produce mayor nivel de concurrencia (nunca hay un
bloqueo), pero tambin el que no garantiza en absoluto la coherencia de los datos.
Vemoslo con un ejemplo; Juan, director comercial de una firma est pensando en
incrementar los precios de ciertos artculos en un 50%, por eso ejecuta una instruccin
en la que incrementa el precio de todos los artculos en ese 50%. El precio de una
camiseta que costaba 30,00 $ pasa a ser en este instante de 45,00 $, aunque como no lo
tiene muy claro todava no lo ha confirmado.
En ese instante Luis, comercial de la misma compaa, crea una factura a su cliente en la
que le vende la camiseta de 30,00 $ a 45,.00 $.
Despus, nuestro indeciso Juan deshace la transaccin esperando a que el gerente
vuelva de vacaciones para cambiar los precios, mientras que Luis confirma el pedido. El
resultado, Luis ha vendido una camiseta a un precio que nunca ha existido en la base de
datos.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

-- Script 1
-- PASO 1
use Northwind
go
set transaction isolation level
read uncommitted
begin tran
update products
set UnitPrice=UnitPrice*1.5
-- Ejecutar hasta aqu y pasar
-- al segundo script
-- PASO 3
-- Ahora desharemos la transaccin
rollback tran
-- Volvamos a comprobar el precio
-- en nuestro segundo script.

81

--Script 2
use Northwind
go
-- PASO 2
set transaction isolation level
read uncommitted
begin tran
--Ejecutamos antes de confirmar
-- o validar la transacin de la
-- conexin 1
select UnitPrice from Products
where ProductId=7
-- El resultado es 45.00
commit tran
-- ahora volvemos al script uno
-- y deshacemos la transaccin
-- PASO 4
select UnitPrice from Products
where ProductId=7
-- Ahora el resultado es 30.00

1.3.10.3 Read Commited


Lecturas confirmadas, en Sql-Server es el nivel de aislamiento por defecto, y supera el
problema de nuestro comercial Luis.
En este caso Luis no habra ledo 45,00 $ como precio sino que permanecera a la espera
de que Juan confirme o rechace los datos para obtener un precio. Si probamos el script
anterior cambiando SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED por SET
TRANSACTION ISOLATION LEVEL READ COMMITTED, el resultado ser bien diferente. En
nuestro paso 2 obtendremos un bloqueo, podemos comprobar el bloqueo ejecutando el
procedimiento almacenado del sistema sp_lock (naturalmente desde la conexin 1) y
obtendremos que hay varios bloqueos de tipo X (Exclusivos) y que un proceso tiene
estado (WAIT) esperando. Si inmediatamente despus de ejecutar el paso 2 ejecutamos
el paso 3 comprobaremos que la segunda conexin nos estar devolviendo el precio del
artculo 7, pero esta vez no nos dir en ningn momento 45,00 sino que el precio
proporcionado ser 30,00.
El nivel de aislamiento Lecturas confirmadas proporciona un nivel de concurrencia muy
bueno y previene del problema de las lecturas sucias, pero no previene de otros
fenmenos como las lecturas no repetibles y datos fantasma.
Las lecturas no repetibles implican que varias instrucciones Select dentro de la misma
transaccin devuelve datos diferentes.
Veamos un ejemplo.
-- Script 3
-- PASO 1
use northwind
go
SET TRANSACTION ISOLATION LEVEL
READ COMMITTED
Begin tran
select ProductName From Products
where ProductId=77
-- resultado 'Original Frankfurter grne
Soe'

www.templatesclarion.com.ar

82

Curso SQL + Clarion - www.templatesclarion.com.ar

El nivel de aislamiento puede especificarse mediante el comando SET o bien mediante los
HINTS de SQL es decir indicando en la propia instruccin SELECT el nivel de aislamiento
deseado, por ejemplo para establecer el mnimo nivel de aislamiento adems de con SET
TRANSACTION ISOLATION LEVEL READ UNCOMMITTED podramos hacerlo en nuestro
ejemplo mediante el comando select UnitPrice from Products with(NOLOCK) where
ProductId=7 y el resultado sera 45,00 independientemente del nivel de aislamiento
indicado con la instruccin SET.
-- Vayamos al Script 4,
-- Paso 3
-- Dentro de la misma transaccin,
-- ejecutamos la misma instruccin
select ProductName From Products
where ProductId=77
Commit tran
-- Se llama de otra forma!!!
-- Volvamos al Script 6, Paso 4

-- Script 4
-- PASO 2
use northwind
go
Begin Tran
Update Products Set
Productname='Producto 77'
where ProductId=77
commit tran
--Volvamos al scrit 5 paso 3
-- Paso 4
-- Volvemos a actualizar al valor correcto.
Begin Tran
Update Products Set
Productname='Original
Frankfurter grne Soe'
where ProductId=77
commit tran

1.3.10.4 Repeatable Read


Lecturas repetibles, este nivel de aislamiento evita el problema que mostraba el script
anterior, es decir si cambiamos el nivel de aislamiento a lecturas repetibles, en nuestro
segundo script el intento de actualizacin quedar bloqueado a la espera de que nuestro
primer script confirme o rechace la transaccin. No obstante este nivel de aislamiento no
soluciona el problema de los datos fantasma.
Los datos fantasma son registros que aparecen y desaparecen dentro de nuestra
transaccin, es decir, un usuario dentro de una transaccin busca el artculo 1500, y no
est, sin embargo varias instrucciones despus, pero dentro de la misma transaccin
vuelve a buscarlo y si existe.
Veamos el ejemplo:

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

-- Script 5
-- PASO 1
use northwind
go
SET TRANSACTION ISOLATION LEVEL
REPEATABLE READ
Begin tran
select * From Products
where ProductId=1500
-- resultado (0 Filas)
-- Vayamos al Script 6,
-- Paso 3
-- Dentro de la misma transaccin,
-- ejecutamos la misma instruccin
select * From Products
where ProductId=1500
-- Ahora aparece un registro!!!!
-- Volvamos al Script 6, Paso 4
-- Paso 5
-- validamos la transaccin
commit tran
-- en este instante se termina el
-- bloqueo y se borra el registro
-- (en la otra conexin)

83

-- Script 6
-- PASO 2
use northwind
go
Begin Tran
-- Product Id es un campo identity
-- en la B.D. Northwind, por eso
-- debemos usar este comando si
-- queremos insertar un valor explicito.
set identity_insert Products on
insert into Products
(ProductId,ProductName)
values (1500,'Producto de pruebas')
set identity_insert Products off
commit tran
--Volvamos al scrit 5 paso 3
-- Paso 4
-- Borraremos el registro..
begin tran
delete from products where
ProductId=1500
commit tran
-- Obtendremos un bloqueo, ya que
-- este dato ha sido leido, por lo que
-- no puede ser eliminado

1.3.10.5 Serializable
El nivel de aislamiento serializable es el que ms se acomoda a lo que significa la
definicin ACID, pero por el contrario no permite una alta escalabilidad y si se usa mucho
puede provocar numerosos bloqueos e interbloqueos. En este caso lo que queda
garantizado es que dos instrucciones Select en la misma transaccin con nivel
serializable van a devolver el mismo conjunto de datos. Esto implica bloquear registros
que incluso No existen todava!, con esto evita el problema de los registros fantasma. Lo
que complica poderosamente su implementacin.
Un hecho que me gustara resaltar para que si usamos este nivel de aislamiento lo
hagamos con precaucin es lo sencillo que resulta producir un deadlock o abrazo mortal
con este nivel de aislamiento.
Probemos este script

www.templatesclarion.com.ar

84

Curso SQL + Clarion - www.templatesclarion.com.ar

-- Script 7
-- Paso 1
use northwind
go
SET TRANSACTION ISOLATION LEVEL
SERIALIZABLE
BEGIN TRAN
-- Obtengamos el nombre del producto
77
SELECT ProductName
FROM Products Where ProductId=77
-- En este nivel de aislamiento hemos
-- creado un bloqueo de tipo compartido.
-- (No confundir con la granularidad
-- del bloqueo, es decir con qu
-- es lo que se bloquea)
-- hagamos lo mismo en el script nmero
8
-- Ahora actualizaremos el nombre del
-- producto
update Products
set ProductName ='Producto 77'
where ProductId=77
-- Obtenemos un bloqueo al intentar
-- convertir el bloqueo compartido
en exclusivo, ya que nuestra
-- segunda conexin tambin tiene un
-- bloqueo compartido sobre este
-- registro.
-- Pasemos al segundo script e
intentemos
-- tambinactualizar el nombre, tampoco
-- es tan raro que dos usuarios
-- quisieran cambiar el nombre a un
-- artculo (por una falta de
-- ortografa por ejemplo)

1.4

Diccionario de Datos (DCT)


Propiedades de Archivos
Tipos de Datos Clarion / MS-SQL
Usando SQLIdentity en Clarion 6
Claves/Indices (Keys)
Integridad referencial - Relaciones
Creacion Tablas en Motor
Conexion a una Base de Datos
Convirtiendo ISAM (Tps) a SQL

www.templatesclarion.com.ar

-- Script 8
-- Paso 2
use northwind
go
SET TRANSACTION ISOLATION LEVEL
SERIALIZABLE
BEGIN TRAN
-- Obtengamos el nombre del
-- producto 77
SELECT ProductName
FROM Products Where ProductId=77
-- Hasta aqu ningn problema,..
-- volvamos al script 7..
-- Ahora actualizaremos el nombre
-- del producto
update Products
set ProductName ='Producto 77'
where ProductId=77
rollback tran
-- El resultado: que la primera
-- conexin obtiene un mensaje de
-- error indicandole que ha sido
-- vctima de un abrazo mortal

Programando con CLARION + SQL (MS-SQL)

1.4.1

85

Propiedades de Archivos
Tab General

DataBase Driver: Este cambio es el mas obvio, necesitamos cambiar de TopSpeed a


"Microsoft SQL" .
Driver Options: Si presionamos el Boton Ellipsis (Tres puntos) nos vamos a encontrar
con una lista de parametros soportados por cada driver, por ej. a continuacion
mostramos una imagen del driver de Microsoft SQL:

www.templatesclarion.com.ar

86

Curso SQL + Clarion - www.templatesclarion.com.ar

Full PathName: El Pathname se utiliza para definir el nombre fsico de la tabla mientras
que se identifica en el servidor.
No RECLAIM : Los drives SQLs no soportan el atributo RECLAIM.

Tab Options

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

87

Esta Seccion nos permite colocar opciones como por ej.. algunas propiedades de la tabla
que nos permita crear determinado cdigo en la generacion de templates.
Por ejemplo hay una opcion importante a partir del Clarion 6.3 a :
IsIdentity :
Esta opcion es a nivel Campo/Columna del DCT y nos permite activar la recuperacion de
un valor auto-incrementing del lado del servidor . De esta forma evitamos insertar a nivel
codigo "SELECT @@IDENTIty....." o "select Scope_Identity() ..." para recuperar el ultimo
numero del lado del motor.
El valor a insertar seria Isidentity =1 en User options.
Es valido aclarar que la columna debera contener el valor "Identity" en la Base de datos..

1.4.2

Tipos de Datos Clarion / MS-SQL


Si utilizamos el "File Import Wizard" o el "Dictionary Synchronizer" automaticamente nos
va a completar las propiedades de las columnas basandose en cada una de las
caracteristicas de las mismas.
Sin embargo, hay algunos "switches" especiales en las caractersticas de la columna que
a futuro se pueden configurar/enviar al "SQL Accelerator Driver" que es el que tiene el
acceso a los datos.
Estos "switches" son descritos abajo y pueden ser aplicados a todos los "SQL

www.templatesclarion.com.ar

88

Curso SQL + Clarion - www.templatesclarion.com.ar

accelerators"con excepcion de ORACLE:

External Name

En primer lugar es valido aclarar que el atributo "External Name" se utiliza tambien para
agregar algun nombre externo a la columna (Campo). Este tipo de caso se puede dar
donde el nombre del campo de la tabla del dct es diferente al nombre de la columna de
la tabla de la base de datos. Por ejemplo si ud. esta accediendo a una tabla de una base
de datos que permiten nombres de columnas mas largos en longitud que Clarion, ud.
puede colocar el nombre que quiere manejar en clarion en el Atributo "Column Name" del
campo y en External Name colocar el nombre de la columna de la tabla del motor de
basedatos.
"Switches" aplicados a "SQL accelerators" en el "External Name":
| NOWHERE
Colocando NOWHERE le estamos diciendo al driver que excluya el campo de cualquier
clausula WHERE que se le envie desde clarion hacia el motor.
| READONLY
Adicionando READONLY le estamos diciendo al driver que no escriba en este campo
cuando el registro es actualizado.
| BINARY
Adicionando BINARY le estamos diciendo al driver que almacene los datos de este campo
en formato Binario. Esto es til al almacenar imgenes o caracteres no-imprimibles
| WRITABLE
WRITABLE es lo contrario a READONLY. Algunos "SQL backends" incorrectamente les

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

89

informan al driver que el campo es " read only" y deberia no ser actualizado. Este
switch informa al driver que puede escribir sobre este campo.
| ZERONOTNULL
ZERONOTNULL es usado en combinacion con el atributo "/ZERODATE=NULL " del "driver
string" . Este switch le informa al driver que este campo fecha en particular sea
actualizado en cero (0) si el mismo es 0.

Tabla Comparativa
En caso de que actualicemos las tablas primero en el dct y luego realizar las
modificaciones en el Motor, o bien realicemos una conversion de TPS a Motor, les
proporcionamos una tabla comparativa/equivalencia entre los tipos de datos MS-SQL y
Clarion:
Categoria

Tipo Dato MS-SQL

Equivalencia Clarion

Numericos Exactos:

Bigint
Decimal
Int
Numeric
Smallint
Money
Tinyint
Smallmoney
Bit

DECIMAL
DECIMAL(19)
LONG
LONG
SHORT
DECIMAL(19,4)
BYTE
DECIMAL(11,4)
BYTE

Numericos Aproximados: Float


Real
Fecha y Hora:

Datetime
Smalldatetime

Caracteres Strings:

REAL
REAL
STRING(8) with GROUP(DATE
and TIME)
STRING(8) with GROUP(DATE
and TIME)

Char
Text
Varchar

STRING
BLOB
CSTRING(51)

Nchar

CSTRING

Ntext
Nvarchar

BLOB
CSTRING

Binary Strings:

Binary
Image
Varbinary

STRING
BLOB,BINARY
STRING

Otros Tipos de datos:

Cursor

n/a

Unicode Caracteres
Strings:

www.templatesclarion.com.ar

90

Curso SQL + Clarion - www.templatesclarion.com.ar

Timestamp
sql_variant
Uniqueidentifier
Table
Xml

STRING(8)
STRING(8016)
CSTRING(37)
n/a
STRING(65535)

Tambien es muy importante al momento de crear/modificar campos en el dct tener en


cuenta Manejo de Fechas y Campos "CSTRING" por "STRING".

1.4.3

Usando SQLIdentity en Clarion 6


A partir de la version 6.3 de Clarion (build 9051) tenemos la posibilidad de recuperar el
valor Identity generado por el motor (Back-End) de una forma muy practica.
Como se hace esto? :

Mediante Codigo Embebido


Muy simple, diciendole al File Driver de Clarion cual/cuales son los campos identity de la
estructura de un archivo. Esto lo hacemos mediante la propiedad "
FILE{PROP:ServerAutoInc, n} = 1 " donde n es el numero de campo dentro de
nuestra estructura de archivo.
Ejemplo:
MyFile FILE,DRIVER('MSSQL')...
RECORD
ID STRING(26) ! columna definida como identity en el servidor
Data STRING(200)

CODE
OPEN(MyFile)
MyFile{PROP: ServerAutoInc} !activamos el "server side autoinc"
MyFile{PROP:ServerAutoInc, 1} = 1 !le decimos al drive el nro de columna en la que se contie
Para que funcione esto obviamente necesitamos que el SQL-Server contenga la correcta definicion de

Mediante IDE de Clarion (Dct)


Otra forma de hacerlo es configurando la columna Identity en las propiedades del campo
de la tabla en el Diccionario de Datos(DCT).

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

91

En este caso, colocamos la Propiedad "IsIdentity" con un valor "true" en la lengueta


"options" de la columna / campo de la tabla.

1.4.4

Claves/Indices (Keys)
Al momento de generar una aplicacion "Clarion SQL" es muy importante en el diseo del
diccionario el manejo de los indices/Claves. Para ello le proporcionamos determinadas
consideraciones al momento de crearlas/modificarlas.

www.templatesclarion.com.ar

92

Curso SQL + Clarion - www.templatesclarion.com.ar

Consideraciones:
1. NO usar tipos de datos "GROUP" en las Claves. Se pueden usar campos que
formen parte de grupos como componentes de una clave, pero no se puede utilizar el
campo "GROUP" como componente. Si en el dct de tps tenemos claves de con este tipo
de dato, deberiamos colocar cada campo que utiliza ese GROUP.
2. Clave Unica (Primaria) Asegurarnos que todas las tablas tengan una clave unica. En
SQL no existe el concepto de puntero de archivo o numero de Registro, entonces para
que el DRIVER pueda actualizar el registro necesitamos tener identificado
univocamente cada registro. Para esto necesitamos tener al menos una clave unica por
cada Archivo. Tengamos en cuenta que el PUT/ACCESS:File.Update() es convertido
por el driver a una sentencia SQL: UPDATE TABLA SET CAMPO = VALOR WHERE
ClaveUnica = Valor
3. CASE SENSITIVE: La mayoria de las base de datos usan el concepto del sensible a
mayusculas a nivel de toda la base de datos. Por tal motivo no se puede especificar
una llave sensible y otra NO. En realidad tambien si usamos claves sin CASE
SENSITIVE puede degradar la performance del motor, ya que las consultas generadas
van a usar la funcion UCASE.
4. IGUALAR CLAVES DE CLARION CON INDICES DEL MOTOR DE BASE DE DATOS:
Con SQL no es necesario que los indices del DCT sean exactamente igual a los del SQL.
Se pueden crear tantos indices en el dct como indices en el SQL independientemente.
Si hay diferencias NO va a a arrojar el error 47 el aplicativo. El driver utiliza los
componentes de las claves para generar el ORDER BY en los Querys. El problema es
que si no existe la clave en el SQL que coincida con ese ORDER BY , la consulta va a
funcionar mucho mas lenta de lo que pensamos.
5. "CSTRING" x "STRING"

1.4.5

Integridad referencial - Relaciones


Integridad referencial significa que, por cada relacin 1:Muchos existe siempre un padre
para cada hijo ( Es decir, que no se permiten hijos hurfanos)

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

93

Las reglas de RI son manejadas mas eficientemente si son definidas en el motor de base
de datos, usualmente utilizando Triggers, Stored Procedures, o sentencias de integridad.
Mediante esto, la base de datos puede automticamente administrar la integridad
referencial,, optimizando el trfico de datos, sin necesidad de enviar a los registros hijos
a travs de la red. (que sera el comportamiento por defecto de Clarion). Como el
servidor de base de datos ser el que maneje la funcionalidad de RI, la mejor opcin es
especificar Ninguna Accin
La integridad Referencial de los datos es recomendable que la maneje el servidor y no
Clarion.
Para ello se utiliza las siguientes configuraciones a nivel Dct:

Restrict
(Server)

El servidor va a prevenir que el usuario desde un "Delete" o "update" pueda


cambiar o borrar un campo si el mismo es usado en una foreign Key

Cascade
(Server)

El servidor va a actualizar/Borrar registros de un campo que es utilizado en


una foreign Key.

Clear
(Server)

El servidor va a actualizar a null o ceros aquellos campos que forman parte


de la foreign Key.

Estos seteos de tipo "server" tienen un mismo comportamiento que el "No Action", no
generan codigo desde clarion, sin embargo nos permiten conocer desde el lado de clarion
cuales son las relaciones y pueden ser usados por algun template de generacion de script
para el server.

Ver mas detalle en Normalizacion_de_la_base_de_Datos

1.4.6

Creacion Tablas en Motor


Utility Template
Synchronizer
File Import

1.4.6.1

Utility Template
Una de las formas de crear una tabla en una base de datos es mediante la creacion de un
script SQL.
Existen varios UTILITY templates circulando gratis dentro de la comunidad de usuarios
que nos permiten generar ese script. Por ejemplo uno de los mas utilizados es el de
Roberto Artigas DCT2SQL.
Una vez que hayamos generado el archivo *.SQL deberiamos ejecutar ese script. Para
esto utilizaremos el SQL Query Analyzer, o el winSQL o cualquier otra herramienta que

www.templatesclarion.com.ar

94

Curso SQL + Clarion - www.templatesclarion.com.ar

nos permita ejecutar scripts SQL en el motor.

1.4.6.2

Synchronizer
Tpicamente, la forma de desarrollar aplicaciones SQL es importando una estructura de
tabla ya definida en el motor de base de datos. Aunque es posible editar manualmente
las estructuras de las tablas en el Editor de Diccionario de datos para tablas SQL,
recomendamos firmemente importar la definicin de la estructura de la tabla. Importar
las estructuras de las tablas, minimiza la posibilidad de introducir un error en el
diccionario y garantiza la correcta especificacin de los tipos de datos , estructuras de las
claves, etc. Este mtodo asume que las tablas ya estn predefinidas en el motor de base
de datos.
Mediante el Synchronizer, Clarion nos permite importar y sincronizar tablas desde el
motor hacia el dct.
El sincronizador del diccionario es probablemente la herramienta ms importante a
dominar al momento de manejar las tabla entre el motor y el dct.
Para acceder al mismo dentro del Editor del diccionario se debera ir al menu File -->
Dictionary Synchronizer.
Los pasos principales a realizar son los siguientes:
Conexion: En este paso se debera establecer los parametros de conexion a la base de
datos a sincronizar.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

95

Direccion: En este paso le diremos al synchronizer desde donde se hara la


comparacion desde Dct a Base o Base a Dct .

Seleccion de Tablas: Seleccionamos con que tablas vamos a trabajar en esta sesion
de Synchronizer .
En el ejemplo de abajo vemos como seleccionamos las tablas "clientes" y "clientes_telef"
que estan en la base y no se encuentran en el dct.

www.templatesclarion.com.ar

96

Curso SQL + Clarion - www.templatesclarion.com.ar

Resolver las diferencias entre la base de datos y el dct: Estas diferencias entre las
caractersticas de la base de datos/DCT necesitan siempre ser resueltas para ser
procesadas:
Una de las principales razones para utilizar el "Synchronizer" es para importar la
definicion de multiples tablas desde la base hacia el dct.
En el ejemplo que vemos abajo, visualizamos que las tablas "clientes" y "clientes_telef"
no se encuentran en el Dct y si en la base de datos (Source). Si presionamos el boton
derecho del mouse en el registro del archivo, veremos un menu popup con acciones a
tomar/decidir. En este caso le decimos que adicione la tabla a "ejemplo.dct" y de esta
manera quedaria resuelto esta diferencia ya que automaticamente al presionar OK nos va
a crear la definicion en el dct importandola desde la Base de datos.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

1.4.6.3

97

File Import
Otras de las posibilidades que tenemos para la creacion de tablas en el dct es
importandola desde el motor.
Para ellos Clarion nos provee de una herramienta en el editor del Dct, a la que podemos

www.templatesclarion.com.ar

98

Curso SQL + Clarion - www.templatesclarion.com.ar

llegar seleccionando el menu File --> Import Table.

Primeramente debemos seleccionar el Driver..

El proximo paso es proporcionarle los datos para la conexion a la Base de datos:

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

Y por ultimo seleccionamos la tabla a importar...

www.templatesclarion.com.ar

99

100

Curso SQL + Clarion - www.templatesclarion.com.ar

En este caso le decimos que adicione la tabla "Clientes_Telef" a nuestro dct y de esta
manera automaticamente nos va a crear la definicion en el dct importandola desde la
Base de datos.

1.4.7

Conexion a una Base de Datos


Owner Name
Para la conexion a una base de datos, Clarion utiliza el atributo Owner para conectarse a
una base de datos. Esto indica cmo conectar con la base de datos donde se localizan las
tablas.
Todas las tablas "SQL" requieren un OWNER (Connect String) y para esto es
recomendable siempre utilizar una Variable Global de tipo CSTRING (255) para setear el
String de conexion hacia el motor.
La conexion con el Server se realiza la primera vez que se abre un archivo. Por mas que
ese archivo se cierre inmediatamente y el aplicativo quede abierto, la conexion se
mantendra abierta hasta el cierre de la aplicacion, o bien hasta que se llame a
prop:disconnet.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

101

Los parametros de conexion del MSSQL son:


servername, database,<uid>,<pwd>
servernam
El nombre del Server o la direccion IP del Servidor
e
database Nombre de la Base de datos
uid

Usuario

pwd

Password

Driver Nativo - SQL Accelerator Drivers


ODBC - Open DataBase Conectivity

1.4.7.1

Driver Nativo - SQL Accelerator Drivers

Database Driver
Lo mas recomendable para aplicaciones de Clarion con MS-SQL es utilizar el driver
Nativo "Microsoft SQL" en Database Driver de las propiedades de la tabla en el dct.
El "SQL Accelerator Driver" es el que nos proporciona el acceso a los datos de la base de
datos.

.
Si importamos las tablas directamente desde el motor (Synchronizer /File Import )
vamos a ver que ya nos viene configurado el driver.
En el caso que creemos una tabla desde cero en el dct debemos seleccionar esta opcion.
Los SQL Accelerator Drivers comparten una base de cdigo comn y muchas
caractersticas como por ejemplo la tecnologa de Buffering, los Driver Strings , etc. Sin
embargo, su objetivo primario es traducir los comandos Clarion en eficientes sentencias
SQL para sus respectivos motores de bases de datos y manejar el resultado que ellos
devuelvan.
Los Accelerator Drivers convierten las sentencias de acceso a disco de Clarion ( SET, GET,
NEXT, etc.) a sentencias SQL optimizadas. Esto significa que puede usar el mismo cdigo
fuente para acceder a tablas SQL y a otros tipos de bases como por ejemplo Archivos
TopSpeed. Adems, los SQL Accelerator Drivers permiten enviar SQL propios que son
enviados directamente al motor e interpretan el resultado para ser procesado de manera
estndar usando los comandos NEXT y PREVIOUS.

www.templatesclarion.com.ar

102

1.4.7.2

Curso SQL + Clarion - www.templatesclarion.com.ar

ODBC - Open DataBase Conectivity

ODBC
El ODBC (Open DataBase Conectivity) es una interfase estratgica de Windows para
acceder a los datos desde diferentes motores
de base de datos (RDBMS) a travs de una variedad de redes y plataformas. Es un
mtodo alternativo a los Drivers nativos. Su funcionamiento es mediante la utilizacin de
DLLs para cada una de las Bases de Datos.
Ventajas: ODBC es una excelente eleccin en un entorno de desarrollo Cliente Servidor,
especialmente si el Servidor es un motor de base de datos relacionales con SQL nativo
(Pervasive, Informix, Oracle, AS400, SyBase, etc..). Permite crear aplicaciones con
soporte Cliente Servidor sin hacer mucho ms que cambiar el Driver. Con ODBC el
Servidor puede manejar la mayor parte del trabajo con las bases de datos, especialmente
si se usan sentencias SQL complejas. Un buen diseo orientado a Cliente Servidor puede
incrementar considerablemente la performance de las aplicaciones.
Los Drivers ODBC existentes actualmente, cubren la mayora de los tipos de bases de
datos. Hay Drivers ODBC disponibles para las cuales Clarion aun no posee Drivers
nativos. (Access, Excel, Notes, etc..)
Cabe mencionar que existe el driver ODBC para tablas tps que nos permite utilizar, entre
otras cosas, algn producto de reportes como Crystal Reports, o algun gestor de
consultas como WinSQL.
ODBC es un estndar muy difundido actualmente, y la tendencia es que todas las bases
de datos ofrezcan acceso ODBC. En muchos casos tenemos disponibles varios tipos de
Drivers para la misma base.
ODBC es independiente de la plataforma. Uno de los principales objetivos de Microsoft al
establecer ODBC fue el de soportar un fcil acceso a los entornos corporativos en los
cuales las bases de datos se encuentran distribuidas en diversas plataformas o mltiples
motores de base de datos.
Desventajas: ODBC agrega una capa el ODBC Driver Manager- entre su aplicacin y la
base de datos. Cuando se accede a datos en su disco local, esto generalmente deteriora
la performance. El Driver Manager debe traducir cada llamada al API ODBC de la
aplicacin a SQL, antes de que ocurra cualquier acceso a los datos.
La informacin requerida por el ODBC para conectarse a una fuente de datos (data
Source) varia de un Driver a otro. Al contrario que la seleccin del Driver nativo de
Clarion en el cual la operacin es virtualmente transparente; Ud. necesitar conseguir
informacin especfica de configuracin de cada Driver.
ODBC no est incluido en Windows. Cuando distribuya su aplicacin, Ud. necesitar
instalar los correspondientes Drivers junto con el Administrador de ODBC en el sistema
del usuario final. Los Drivers ODBC pueden ser configurados desde el Administrador de
ODBC del Panel de Control. Es muy comn que el usuario final utilice incorrectamente
esta herramienta, y casi cualquier cambio en la configuracin de los data sources har
que nuestra aplicacin deje de funcionar por resultarle imposible conectarse a la fuente
de datos, o peor aun hara que se conecte de manera ineficiente degradando la
performance o provocando su mal funcionamiento

1.4.8

Convertir TPS a SQL


Para convertir una Aplicacion "TPS" a "Client Server", se deben tener en cuenta
determinados tips que vamos a detallar a continuacion...

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

103

CREACION DE DCT
Primeramente para realizar las modificaciones al DCT de Clarion debemos hacerlo a
partir de un nuevo diccionario y tenemos tres posibilidades de hacerlo:
1. Copiando el archivo "*.dct"

o haciendo un " Save As" en el diccionario original.

2. Exportando el diccionario a un TXD e importando en un nuevo Dct.


3. Creando un nuevo diccionario y haciendo Copy/Paste de cada uno de los archivos de
dct origen hacia el nuevo. Las desventajas de esto son que las relaciones no se van a
copiar, y el tiempo que se insume si el diccionario es demasiado grande.
Una vez creado el nuevo Diccionario, se debera realizar los siguientes cambios al Dct:

DataBase Driver: Este cambio es el mas obvio, necesitamos cambiar de TopSpeed a


"Microsoft SQL" .
Si se utilizo metodo de "TXD" para la creacion del nuevo diccionario , se podria hacer sobre el mismo antes de
importarlo una busqueda "'TopSpeed')"
y reemplazar con "'MSSQL'),OWNER(GLO:OwnerName)".

"CSTRING" por "STRING"


Manejo de Fechas
Migrar Datos Existentes

www.templatesclarion.com.ar

104

Curso SQL + Clarion - www.templatesclarion.com.ar

No RECLAIM : Los drives SQLs no soportan el atributo RECLAIM, por ende debemos
sacar este atributo para las aplicaciones SQL.
(Si se utilizo metodo de "TXD" para la creacion del nuevo diccionario , se podria realizar una busqueda
"RECLAIM,"
y reemplazar con "")

TIPOS DE DATOS
Otro de los grandes cambios a considerar dentro de la migracion de un aplicativo de tps a
Motor son los tipos de Datos.
LONG a DATE (Fecha) / TIME (Hora)
En los sistemas TPS, generalmente los datos de fecha y Hora se almacenan como LONG.
Estos se deben convertir a DATE y TIME ya que desde clarion se van a serguir trabajando
sin problemas, pero para que los datos sean accesibles desde herramientas externas a
Clarion como por ej. Crystal R eports, Reporting Services, etc. es necesario realizar la
conversion. ( ver manejo de Fechas)
MEMO a CSTRING :
Los drivers SQLs no soportan campos con tipos de datos MEMOs, por tal motivo es
necesario cambiar a tipo de dato CSTRING.
Ver Tipos de Datos Clarion / MS-SQL para mas detalle con respecto a los tipos de datos
Clarion / MS-Sql.

CLAVES (keys):
Recomendamos revisar Claves/Indices (Keys) de este manual para realizar las
modificaciones correspondientes al manejo de Claves/indices de una tabla.

1.4.8.1

"CSTRING" por "STRING"


En la mayora de las bases de datos SQL, los espacios en blanco al final son importantes
al momento de comparar igualdad entre campos. Por ejemplo "Cliente " no es lo mismo
que "Cliente" para los motores. Este concepto es muy importante para aquellos campos
que son componentes de claves. Si se utilizan campos de tipo "CSTRING" Clarion trata
los espacios de igual manera que los motores. Al utilizar este tipo de campo se debera
incrementar el tamao de la columa en uno, ya que el CSTRING tiene un caracter
adicional para indicar el fin de la cadena.

1.4.8.2

Manejo de Fechas
En sistemas con archivos TPS, generalmente los datos de fecha y de la hora se
almacenan como tipo de datos LONG. Estos se deben convertir a Campos DATE y TIME,
para que los mismos sean facilmente accesibles desde herramientas de terceros. O sea si

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

105

dejamos los campos como LONG (INT en el Motor) lo vamos a seguir trabajando sin
problemas desde Clarion, pero no se van a ver correctamente por ej. desde el SQLEditor
o desde Cristal Report, Reporting Services,etc..

Microsoft utiliza dos tipos de datos para identificar informacion de fecha y hora :
SMALLDATETIME y DATETIME.
En ambos casos se manejan de la misma manera en clarion:
Aud_Fecha STRING(8)
GFecha GROUP,Over(Aud_Fecha)
Aud_Fecha_Date DATE ! Ud. debe modificar este campo (fecha)
Aud_Fecha_Time TIME ! Ud. debe modificar este campo (Hora)
END

Un dato muy importante, es que si Ud. no necesita manejar la Hora dentro de su campo
de Fecha , puede cambiar la definicion de arriba a:
Aud_Fecha
1.4.8.3

DATE

Migrar Datos Existentes


Si Ud. esta convertiendo un aplicativo TPS a Motor, es muy factible que quiera migrar sus
datos.
Les comentamos algunas opciones al respecto:
Realizando un procedimiento de conversion para cada una de las tablas a migrar.
Utilizando el DTS de Ms-Sql conjuntamente con el driver ODBC de "Topspeed "
Exportando las tablas Tps a ASCII de tipo CSV (delimitado por comas) y e importarlos
a traves del DTS - Importacin y exportacin de datos

1.5

Usando SQL en Aplicaciones (APP)


Recomendaciones
Ventana de Login Automtico
Validacion de Datos
SQL Embebido en Clarion
Prop:SQL
Comando BUFFER
Prop:SQLFilter
Prop:WHERE
SetFilter con codigo SQL
Filtrando Campos DATE

www.templatesclarion.com.ar

106

Curso SQL + Clarion - www.templatesclarion.com.ar

StupidTempTable
Codigo Clarion Vs. SQL
Manejo de Errores
Manejo Set, Next, Previous
Clarion y NULLs
SQL / VIEWs
Browses
SQL Advanced Tab
Process /Reports
Transacciones Batch
Manejo de Transacciones
Stored Procedures
Usando TurboSQL
Uso del trace
Cargas de Cabecera - Detalle
Creando un Editor de SQL

1.5.1

Recomendaciones
Este es un resumen de las consideraciones a tener en cuenta al desarrollar una
aplicacion Cliente Servidor.
Estas consideraciones tienen como objetivo evitar problemas tanto de performance
(lentitud) como de errores en el funcionamiento de nuestra aplicacin.
El objetivo de una aplicacin Cliente Servidor es distribuir coherentemente el trabajo
entre la terminal Cliente y el Servidor de Base de Datos.
Mas que nada hay que tratar de evitar la sobrecarga de trabajo en el servidor y
minimizar el volumen de trafico por la red.

Lista de items a considerar


Uso de SQL Embebido
En Clarion no es obligatorio usar SQL Embebido para todo, ya que los drivers generan
automaticamente el SQL necesario para resolver los comandos Clarion (ADD, PUT, etc..)
Sin embargo, siempre que necesitemos que un proceso funcione lo mas rapidamente
posible, deberemos recurrir al SQL embebido.
Esto es fundamentalmente critico en los procesos. Tengamos en cuenta que un Process
de clarion recorre cada unos de los registros y realiza las actualizaciones de a una. Un
solo comando SQL puede hacer todo el trabajo de nuestro proceso 10 veces mas rapido.
Mejor todavia, si usamos un Stored Procedure, va a funcionar mas rapido porque ya
queda precompilado en el motor.
Transacciones (LOGOUT) en cargas de Cabecera Detalle
Siempre que agregamos o modificamos datos dentro de un LOGOUT estos datos quedan
Lockeados. Si algun browse o reporte intenta leer estos datos va a quedar colgado.Por
esto las transacciones deben ser siempre lo mas cortas posible. Nunca se debe dejar una
transaccion abierta con algun mensaje o intervencion pendiente del usuario.
Un ejemplo claro de mala practica es iniciar una transaccion (LOGOUT) en el Init de una
carga de cabecera / detalle, un COMMIT en el TakeCompleted y un ROLLBACK en el
Cancel. Todos los registros que se agreguen estan lockeados hasta que el usuario no se
decida, generando lockeos con otras terminales.
Lo que debe hacerse es trabajar todo en memoria o tablas auxiliares y confirmar todo el
procesamiento transaccional en el minimo tiempo posible (generalmente en el

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

107

TakeCompleted).
Claves Primarias en las Tablas
En SQL no existe el concepto de puntero del archivo. Para actualizar un registro se
necesita obligatoriamente algun campo o grupo de campos que definan univocamente el
registro. Esto es: Una clave primaria.
Para que el driver convierta los PUT o DELETE en sus correspondientes sentencias SQL,
tiene que especificar la sentencia Where sobre la que se va a realizar la actualizacion.
Por ejemplo
(Primero posicionarse con NEXT, o GET)

ORD:Saldo = 0
PUT(Ordenes) ACCESS:Ordenes.Update()
Se traduce como:

UPDATE Ordenes SET Saldo=0 WHERE NumeroOrden = 234


Donde NumeroOrden es el campo de la Clave Primaria

Uso de Claves Sensitivas


El uso de CASE sensitive es obligatorio para todas las claves que contengan algun campo
alfanumerico. Si no ponemos el check de Case Sensitive el Driver (correctamente) le va a
poner UPPER en el ORDER BY por esos componentes. Esto hace que el SQL no pueda
usar la clave y que funcione muy lento.
Igualar las claves de Clarion con los indices SQL
Con SQL no es necesario que los indices en el DCT sean exactamente iguales a los del
SQL. Se pueden crear tantos indices en el DCT como indices en el SQL
independientemente. Por mas que tengamos diferencias no va a dar Error 47.
El driver simplemente utiliza los componentes de la Clave para generar el ORDER BY.
El problema es que si no existe la clave en el SQL que coincida con ese ORDER BY, la
consulta va a funcionar igual pero mucho mas lento.
Uso del OWNER Name
Es fundamental que asignemos una variable global GLO:Connexion en el Owner name
de todas las tablas. Esto es asi porque es muy comun que el nombre del server, de la
base o del usuario cambien.
Recordemos que el formato de esa variable de Conexin deberia ser
server,base,usuario,password (si se usa ODBC, consultar el Anexo)
Uso del Full PathName
En SQL, al importar la tabla nos queda usuario.tabla en el full pathname (generalmente
dbo.tabla)
Es recomendable dejar solo el nombre de la tabla, para que sea independiente del
usuario.
Autonumeracion
Lo mejor es usar un campo identity siempre que se pueda. Y en lo posible tratar de no
usar la autonumeracion estandar de Clarion.
Revisar el capitulo de Autonumeracion

www.templatesclarion.com.ar

108

Curso SQL + Clarion - www.templatesclarion.com.ar

Campos Cstring
Cambiar todos los campos STRING(n) del DCT por CSTRING (n+1). Los campos STRING
dan muchos problemas, mas que nada en las claves y busquedas
Definir solo los campos que se usan
En algunos casos no es necesario tener en el DCT todos los campos de la tabla.
Por ejemplo podemos tener campos adicionales de auditoria en las tablas con valores por
default que no es necesario esten en el DCT.
Transacciones en procesos
Siempre que necesitemos hacer un proceso y no podamos usar SQL, es conveniente
encerrar todo el procesamiento en un bloque LOGOUT COMMIT.
De esta manera el SQL confirmara todo el lote de comandos cuando llegue al COMMIT.
Siendo el proceso mucho mas rapido.
Evitar los Relation Trees
El Relation Tree es un control Template que consume bastantes recursos.
Hay que evitar usarlo y mas aun si el primer nivel del arbol es muy grande ya que
siempre carga los niveles completos en memoria.
Acerca de los Browses

1.5.2

Ventana de Login Automtico


Los SQL Accelerator Drivers automticamente buscan por el Nombre del Usuario y
Password al acceder a las tablas. Si el nombre de usuario y el Password fueron
ingresados entonces el Driver usa esos valores. Si no se han ingresado estos datos,
entonces el Driver trae la ventana automtica de Login.
Se recomienda abrir una tabla al inicio del programa, as el tiempo de conexin con el
servidor ocurre solamente al abrir la aplicacin; para realizar esto ud. puede agregar
una tabla SQL en el File Schematic del procedimiento main. Esto automticamente
genera cdigo de conexin y apertura de la tabla.
Excepto por el ODBC Accelerator Driver, el dialogo automtico de Login le permite al
usuario especificar Nombre de Usuario, Password, y Base de datos.

1.5.3

Validacion de Datos
La validacin de los datos se refiere al cumplimiento de las reglas del negocio
(especificadas por el programador). En particular, los valores que cada campo pueda
tomar en la base de datos. Algunas validaciones tpicas fuerzan cosas como : un campo
no puede ser dejado en blanco (o cero) , el campo debe contener un valor 1 0 , el
campo debe estar en un determinado rango, el campo debe existir en una clave primaria
de otra tabla.
Estas reglas de validacin pueden ser especificadas tanto en el Cliente como en el
Servidor. La mejor manera de implementar este tema es minimizando el trfico de red,
por ende la mejor solucin sera resolverlo en el cliente. Alternativamente, puede
duplicarse esta lgica y estar definida en ambos lados logrando as el siguiente esquema:
Al declarar las reglas de validacin en el Cliente se asegura que los datos enviados
por el Cliente sean vlidos. Ya que el servidor va a recibir siempre datos vlidos (de
esta aplicacin) entonces nunca generar mensajes de error. El efecto es que esta

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

109

situacin reduce el trfico en la red.


Al declarar las reglas de validacin en el Servidor se asegura que los datos son
siempre vlidos, sin importar que aplicacin sea la que este accediendo a la base de
datos en ese momento. Al interactuar con herramientas SQL un usuario podra
corromper los datos.

Forzando estas reglas en ambos lados pareciera aumentar el trabajo de programacin.


Sin embargo, el Editor de Diccionario de Datos nos permite seleccionar de manera
sencilla las reglas mas comunes a partir de opciones prefijadas, afectando la definicin
del campo. Al hacer esto, la aplicacin generar el cdigo necesario para forzar el
cumplimiento de estas reglas en toda la aplicacin.

Definicin de las reglas del Negocio


La Definicin de las reglas del Negocio puede hacerse tanto en el cliente como en el
servidor, por supuesto que definindola del lado del cliente obtengo un nivel mucho mas
alto de flexibilidad ya que el nivel de expresin del lenguaje de desarrollo de aplicaciones
en el cliente supera ampliamente lo que puedo lograr en el servidor.
De todas maneras definiendo las reglas en el servidor mediante views, stored procedures
y triggers centralizo el problema, y generalmente se logra un gran incremento en la
performance.
Al momento de analizar que lgica va del lado del cliente y cual del lado del servidor
generalmente se opta por la solucin que minimice el trafico de la red y los tiempos de
respuesta. Es similar al problema de la validacin de datos, pero normalmente el tipo de
lgica involucrada es mas compleja. Por Ejemplo: a los clientes cuya categora de iva es
"Resp. Inscripto" se les confecciona factura del tipo "A"

1.5.4

SQL Embebido en Clarion


La tecnologa de los File Drivers de Clarion le permite al programador Clarion tener que
aprender y usar solamente la sintaxis de los comandos I/O del Lenguaje Clarion, sin
importar sobre que base de datos est trabajando. El File Driver automticamente
convertir esa instruccin a una instruccin SQL vlida. Es por eso que al utilizar un
Driver basado en motores SQL, es el Driver en si mismo el que genera los querys SQL
necesarios para retribuir los datos desde el servidor.
Usando toda la informacin que el File Driver puede obtener de la estructura de la tabla,
la estructura del VIEW (vista) y del comando BUFFER, el SQL generado puede llegar a
ser bastante eficiente. Pero sin embargo, existen casos en donde un experimentado
programador SQL querr extender esta funcionalidad o tomar total control sobre el SQL a
generar. Algunas operaciones como borrar un bloque entero de registros no es realizado
por los File Drivers por lo cual en ese caso tambin es recomendable tomar el control del
SQL a generar.
Para estos casos, el lenguaje Clarion provee un mecanismo para enviar SQL directo al
motor de base de datos : Prop:SQL.

1.5.5

Prop:SQL
Prop:SQL es la propiedad de una Tabla o una Vista que permite enviar cualquier SQL
directo al motor de base de datos.

La sintaxis de Prop:SQL es la misma que cualquier otra propiedad del lenguaje Clarion. El target (dest
MiTabla{Prop:SQL} = SELECT * FROM UnaTabla

www.templatesclarion.com.ar

110

Curso SQL + Clarion - www.templatesclarion.com.ar

Esta sentencia SQL es enviada al motor de base de datos. Notar que el Target
(destinatario) de la propiedad es MiTabla mientras que el query se refiera a UnaTabla.
Debido a que un SELECT retorna un grupo de registros entonces hay que utilizar el
comando NEXT() para retribuir un registro a la vez. La estructura de la tabla MiTabla
deber tener la misma cantidad de campos que UnaTabla. El ejemplo anterior no
demuestra el mtodo optimo ya que los File Drivers generaran un mejor query, y
adems automtico, para resolver esta consulta.
La verdadera potencia de PROP:SQL es realizar tareas y/o funciones que no tengan su
respectiva contrapartida en el Lenguaje Clarion. Un ejemplo sera la creacin de tablas en
el servidor de base de datos. Aunque el comando CREATE crea las tablas este est
limitado por la informacin guardada en la estructura de la tabla. Es mucho mejor utilizar
en este caso PROP:SQL para crear la tabla ya que podemos agregar mas informacin
como por ejemplo validacin de datos , restricciones, etc. Por ejemplo, el siguiente
cdigo permite crear la tabla de Estudiantes:
MiVista{PROP:SQL} = CREATE TABLE
(CodEstudiante
Apellido
Nombre
CodCarrera
PRIMARY KEY
FOREIGN KEY
REFERENCES
ON DELETE

Estudiantes
INTEGER NOT NULL,
VARCHAR(25) NOT NULL,
VARCHAR(25) NOT NULL
INTEGER,
(CodEstudiante),
CURSA (CodCarrera),
Carreras,
RESTRICT)

&|
&|
&|
&|
&|
&|
&|
&|
&|

Este SQL especifica dos cosas que son imposibles de hacer usando el CREATE de Clarion.
Primero, el atributo NOT NULL especifica que deben existir datos en esa columna.
Segundo, la condicin de integridad referencial especifica la relacin entre la tabla de
Estudiantes y Carreras indicando que no se puede borrar una carrera si esta tiene
estudiantes.
Otra utilizacin de PROP:SQL es el llamado a Store Procedures (Procedimientos Creados
en la base de datos utilizando SQL extendido). En la mayora de bases de datos basados
en SQL los Store Procedures contienen una versin pre-compilada de sentencias SQL .
Debido a que los Store Procedures estn guardados en la base de datos nos permite una
mejor integracin y reusabilidad entre distintas aplicaciones.
El uso de SQL embebido es particularmente eficiente en procesos de actualizacin
masivos de la base de datos, y es en este punto donde podemos utilizarlo para marcar
una gran diferencia en los tiempos de respuesta entre el cdigo Clarion nativo y el SQL.
Por ejemplo si queremos aumentar en un 5% los precios de los productos de
determinado rubro se puede utilizar la siguiente sentencia SQL en lugar de un proceso
Clarion.
MiTabla{PROP:SQL} = UPDATE Productos SET &|
precio=precio * 1.05 WHERE rubro=X
Ntese que los nombres usados en las sentencias SQL son los del servidor, no los de
Clarion. O sea ponemos rubro (o tabla.rubro) en lugar de PRO:RUBRO.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

1.5.6

111

Comando BUFFER
El comando BUFFER de Clarion puede tener un impacto tremendo en la performance de
aplicaciones Cliente/Servidor. BUFFER le indica al Driver que utilice un buffer para
almacenar registros previamente ledos como as tambin un buffer para registros
read-ahead (Lectura Anticipada) . Tambin permite especificar el tiempo de time-out
de una pgina. Es decir, el tiempo de vencimiento de una pgina de datos. Luego de
vencerse este tiempo el Driver vuelve a leer esta pgina al buffer.
Cuando el File Driver sabe que tiene buffers para guardar mltiples registros puede
optimizar los querys para aprovechar esta capacidad. Esto permite que el servidor
devuelva varios registros a la vez (grupo de registros) en lugar de regresar de a uno por
vez. Esta tcnica se la conoce con el nombre de Fat Fetches (Lecturas Gordas). El
efecto neto de este cambio es que ahora en lugar de tener muchos paquetes pequeos
viajando por la red tenemos uno mas grande (haciendo mas eficiente el trfico de la
red). El lugar mas comn para la utilizacin del comando BUFFER sera en
procedimientos que permitan al usuario realizar un Browse de Registros de la base.
Al utilizar buffers para guardar registros ya ledos, el cliente al necesitar nuevamente
estos registros los trae del buffer de memoria en lugar de necesitar realizar otro query y
esperar su resultado, logrando as una gran reduccin de trfico en la red.
Al utilizar buffers de Lectura Anticipada, la aplicacin cliente se anticipa y trae a memoria
la prxima pgina de registros mientras el usuario est leyendo la primer pgina. De esta
manera, cuando el usuario realmente pide la prxima pgina esos registros ya se
encuentran en el buffer dndole al usuario la sensacin de retribucin instantnea.

Nota especial con PROP:SQL


La siguiente nota es un extracto de una documentacion de Rick Hoffman's.:

Cuan se utiliza un prop:sql con el comando BUFFER(TableName, 0) antes del PROP:SQL le estamos i
BUFFER(TableName, 0)
TableName{PROP:SQL} = 'SELECT Field1, Field2, FROM TableName'
NEXT(TableName)

Ahora bien, tambien podemos utilizar BUFFER(TableName, 20) y de esta forma le estamos diciendo a
Por Ejemplo:
BUFFER(TableName, 20)
TableName{PROP:SQL} = 'SELECT Field1, Field2, FROM TableName'
NEXT(TableName).

1.5.7

Prop:SQLFilter
Prop:SQLFilter es la propiedad que permite agregar un filtro propio a la estructura
WHERE de una sentencia SQL enviada al motor de base de datos.
Esta propiedad permite especificar un filtro para una estructura Tabla y/o Vista utilizando
la sintaxis del servidor en lugar de la sintaxis de Clarion.
Por defecto, Prop:SQLFilter reemplaza cualquier expresin en el atributo Filter. Sin
embargo, al comenzar el filtro con el smbolo +, el File Driver adicionar este filtro al
filtro ya existente de acuerdo al atributo FILTER del SQL generado.

www.templatesclarion.com.ar

112

Curso SQL + Clarion - www.templatesclarion.com.ar

La ventaja de utilizar Prop:SQLFilter es la posibilidad de utilizar las capacidades del


motor en cuanto a la sintaxis del filtro. Por ejemplo:
El cdigo siguiente usar el atributo FILTER para limitar la vista a los estudiantes de
Computacin y se agregar un Filtro usando Prop:SQLFilter para que retorne nicamente
aquellos estudiantes cuyos nombre comiencen con Al ( Como por ejemplo Aldo, Alfredo,
Alfonso )
MiVista VIEW(Estudiantes),FILTER(Est:Carrera=Computacin)
PROJECT(Est:Apellido,Est:Nombre,Est:Carrera)
END
CODE
OPEN(MiVista)
MiVista{PROP:SQLFilter} = +Estudiantes.Apellido LIKE Al%

Esto hubiera sido muy costoso de realizar de no ser por el PROP:SQLFilter.


Ntese que en el atributo FILTER se utiliza la nomenclatura de los campos segun su
definicion en el DCT, mientras que en la propiedad PROP:SQLFilter se utiliza la
nomenclatura de los campos segun su definicion en el motor de base de datos.
Otro Ejemplo:
Supongamos que queremos ver en el browse solo los Clientes que tienen Ordenes, esto
es muy dificil de hacer con codigo Clarion, pero en SQL queda:
BRW1.Reset PROCEDURE
CODE
BRW1.view{PROP:SqlFilter} =

'+EXISTS (SELECT * FROM ordenes B

WHERE A.CodCliente =

....
PARENT.Reset()

1.5.8

Prop:WHERE
Prop:Where es la propiedad que permite agregar un filtro propio a la lectura secuencial
de un archivo (conjuncion de LOOP NEXT (FILE), etc ), utilizando la sintaxis del servidor
en lugar de la sintaxis de Clarion.
PROP:WHERE puede setearse tambien en el diccionario como una propiedad del "driver
string", pero esto no va a afectar el comportamiento de los Views.
Ejemplo:
Supongamos que queremos procesar todas las compras de un Cliente del ao actual:
Clear(Ord:Record)
Ord:CustomerId = 100
Set(Ord:K_CustomerId,Ord:K_CustomerId) .
Orders{Prop:Where}='Year(OrderDate)=Year(GetDate())'
Loop Until Access:Orders.Next()
!......... procesamiento de datos

END
Esto genera el siguiente query SQL:
select ...
www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

113

from Orders
where CustomerId >= 100
and Year(OrderDate)=Year(GetDate())

Ntese que PROP:Where debe estar ubicado luego del SET y antes del LOOP. Tenga en cuenta que la

1.5.9

SetFilter con codigo SQL


Otra posibilidad de adicionar un filtro para una estructura Tabla y/o Vista, es utilizando la
sintaxis 'SQL()' dentro del metodo SetFilter() de la Clase ViewManager.
Por Ejemplo supongamos que queremos filtrar un browse de Provincias cuyo codigo
(Idprovincia) se encuentre en la tabla Clientes:

Brw1.SetFilter('SQL(Idprovincia IN(Select idprovincia from Clientes))')


ThisWindow.Reset(1)

1.5.10 Filtrando Campos DATE


Cuando manejamos campos de tipo "DATE" en un archivo, al momento de realizarle un
filtro y comparar con este tipo de datos, debemos considerar el "Format" del mismo para
su correcto funcionamiento.
En SQL-Server el picture del FORMAT debe ser "@d12-" al momento de generar el "Query
string".
En caso de que no utilice el FORMAT() con un picture valido es muy factible que al
momento de ejecutar el query en clarion nos arroje el siguiente error:

Ejemplo:
A continuacion describimos un ejemplo de un query en el que se filtran todas aquellas
ventas que ser realizaron en un dia determinado (Variable Loc:Fecha). En el mismo
notamos que la fecha es tratada como tipo de dato STRING, o sea con comillas dobles al
momento de comparar - Shippeddate = ''' & FORMAT(Loc:Fecha,@d12-)& ''''.
En este caso tambien observamos que al momento de recibir y guardar el dato de Tipo
DATE (OrderDate/R:Campo4) tambien se le realiza un DEFORMAT() con picture "@d10-"
para visualizar la fecha correctamente.

Loc:Query = 'select customerId,shipName,ShipAddress,OrderDate from orders


' Where Shippeddate = ''' & FORMAT(Loc:Fecha,@d12-) & ''''
ResSQL{prop:sql} = Loc:Query

www.templatesclarion.com.ar

!! enviamos el query al Motor

'&|

114

Curso SQL + Clarion - www.templatesclarion.com.ar

IF FILEERRORCODE() !! mapeamos el error


SETCLIPBOARD(Loc:query) !! colocamos al Clipboard el query por si queremos ejecutarlo de
MESSAGE('Atencion Ocurrio un error ='&FILEERROR(),'ERROR',ICON:HAND)
return LEVEL:Fatal
END
FREE(QClientes)
Loop Until Access:ResSQL.Next()
QC:IdCliente
= R:Campo1
QC:Razon_Social
= R:Campo2
QC:Direccion
= R:Campo3
QC:Fecha
= DEFORMAT(R:Campo4,@d10-)
ADD(QClientes) !! Cargamos un queue para visualizarlo en un Control List
END

!!!Resultado de la consulta

1.5.11 StupidTempTable
Para que necesitamos esta teoria?
Esta teoria se utiliza para los siguientes casos:
Para obtener y manipular facilmente campos calculados por el server. (Esto se puede

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

115

aplicar a funciones como sum, avg, max, etc como tambien a la llamada de stored
procedures)
Para no tener que establecer relaciones en el diccionario por cada JOIN que se nos
ocurra usar.
Para no necesitar definir una clave por cada ordenamiento que necesitemos de las
tablas, independientemente de las relaciones entre las mismas.

Como funciona esta teoria?


En el server existe una tabla de validacion (StupidTempTable) con un campo por cada
tipo de dato que usemos en nuestra aplicacion.
Esta tabla no va a existir en nuestro diccionario de Clarion, sera definida en la DATA
SECTION de cada procedimiento.
Al definir la tabla local en el procedimiento se le asigna el atributo NAME tanto de la tabla
como de cada uno de los campos que se desea retornar. El Driver de Clarion no verifica
el orden, o el tamao, solo que el nombre del campo exista en el SQL y tenga el mismo
tipo de datos.
Se pueden definir y abrir tantas tablas locales como se necesiten, cada una de ellas
haciendo referencia a la misma StupidTempTable, obviamente todas ellas tendran
diferente nombre, pero el mismo atributo NAME (Asegurese de cerrarlas una vez que
termine de usarlas)
Se pueden tener tantos campos en la tabla temporal como se necesiten con el mismo
atributo NAME, obviamente sin repetir sus nombres.

Tecnica de la Tabla Temporal


Creacion de Tabla de Validacion en el server:
Solo es necesario una.
StupidTempTable
X_INT INT
X_VARCHAR VARCHAR(255)
X_CHAR CHAR(255)
X_DECIMAL DECIMAL(12,2)
X_MONEY MONEY
X_TEXT TEXT
ETc..

Creacion de Tabla Local en el procedimiento:


En el embed DATA SECTION.
TempTable FILE,DRIVER(MSSQL)
NAME('StupidTempTable'),
OWNER(GLO:Owner),PRE(Stt)
Record RECORD
Id_Proveedor LIKE(Pro:IdProveedor),NAME('X_INT')
Razon_Social LIKE(Pro:RazonSocial),NAME('X_VARCHAR')
Nombre
LIKE(Pro:Nombre),NAME('X_VARCHAR')
Credito
DECIMAL(12,2),NAME('X_DECIMAL')
Distancia
LONG,NAME('X_INT')! Calculado por el Server (Query)

END
END
Obteniendo Informacion y asignacion de valores a una variable:

www.templatesclarion.com.ar

116

Curso SQL + Clarion - www.templatesclarion.com.ar

TempTable{prop:sql} = 'Select p.idproveedor,p.RazonSocial,p.Apellido_Nombres,LimiteCre


' Round(sqrt(power(p.XCoordeanda - a.XCoordenada,2)+power(p.YCoordeanda - a.YCoordenad
' from proveedores p, posiciones a where estado = <39>A<39> and p.idproveedor = a.idpr
!Procesamiento de Lectura de Registros.
LOOP
NEXT(TempTable)
IF ERRORCODE() THEN BREAK.
L:Variable_Codigo_Proveedor = Stt:Id_Proveedor
L:Variable_Nombre
= Stt:Nombre
L:Variable_Distancia
.... etc.

= Stt:Distancia

END

Tecnica de la Tabla Temporal SIMPLIFICADA


Si bien es muy poderosa la tecnica anterior, el problema que tiene es que resulta bastante engorroso
declarar las tablas temporales en cada procedimiento.
Una opcion mas sencilla es crear en el diccionario una tabla con campos de tipo CSTRING.
Por Ejemplo:

Respuesta FILE, DRIVER('MSSQL'),OWER(Glo:Owner),NAME('dbo.SQL_Temp'),PRE(SQL),CREATE,B


Record
RECORD,PRE()
C1 CSTRING(255)
C2 CSTRING(255)
C3 CSTRING(255)
......
C20 CSTRING(255)
END
END
Cuantos Campos?
Le creamos tantos campos de Tipo de datos CSTRING como necesitemos para las
consultas de nuestra aplicacion.
No hay ningun inconveniente en crear varias tablas temporales en el diccionario para que
se ajusten a nuestros requerimientos. Por ejemplo es mas rapido tener una tabla
temporal solo con un campo de tipo LONG para realizar sumatorias, maximos, etc. desde
la base.
Por que Tipo de Datos CSTRING?
Porque el tipo de dato CSTRING mapea automaticamente contra cualquier tipo de datos,
por lo tanto cualquier cosa que pongamos en el select se va a asignar en el mismo orden
a los campos CSTRING, sin importar el tipo de dato. Los datos nos van a llegar
formateados como alfanumericos, en algunos casos es necesarios aplicarles un
DEFORMAT para poder manipularlos mejor (especialmente las fechas).

1.5.12 Codigo Clarion Vs. SQL


Ventajas de cada tecnica

Clarion: Codigo generico. Funciona para cualquier Driver (TPS / SQL)


SQL Embebido: Rapido. Actualiza desde el server cada sentencia SQL (UPDATE,

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

117

DELETE, ...)
Stored Procedure: Muy Rapido. Ejecuta dentro del server muchas sentencias SQL
complejas. Pre compilado y optimizado. Utiliza SQL extendido (LOOP, IF, ....)

Desventajas de cada tecnica

Clarion: Muy lento en Batch. Actualiza desde el Cliente cada registro


SQL Embebido: No es generico. A veces Depende del Server. Solo funciona con
motores
Stored Procedure: Complejo. Siempre depende del server. Agrega complejidad al
proyecto. Dificil de debuggear y mantener

1.5.13 Manejo de Errores


Al ejecutar una operacin de I/O existe la posibilidad que se produzca un error. No
importa que base de datos se est utilizando, el File Driver de Clarion mapea los errores
mas comunes al apropiado ERRORCODE().
Sin embargo, existen siempre algunos errores que no tienen equivalencia con los errores
de Clarion.
Cuando ocurren este tipo de errores , que no tienen equivalencia con los errores
estndares de Clarion, se retorna el ERRORCODE()=90 y la funcin ERROR() devuelve el
texto File Driver Error. Para determinar el verdadero error y el texto de error hay que
utilizar las funciones FILEERRORCODE() Y FILEERROR() respectivamente.
Las funciones FILEERRORCODE() Y FILEERROR() contienen el cdigo de error del motor
de base de datos y el texto que esta devuelva.

Tip: Estos cdigos de error figuran en la documentacin del producto de la base


de datos y no en la documentacin de Clarion.

1.5.14 Manejo Set, Next, Previous


Procesamiento de SET/NEXT y SET/PREVIOUS (SELECT/ORDER
BY)
Una sentencia SET seguida de un Next en una estructura LOOP es el mtodo mas comn
de procesar datos secuencialmente en Clarion. Cuando el SQL Accelerator Driver
encuentra una combinacin SET/NEXT, genera una sentencia SQL SELECT con la clusula
ORDER BY basada en los componentes de la clave. Los campos componentes de la clave
se determinan al momento del SET.
Ejemplo:

Ord:Nombre = PEREZ
SET(Ord:Nombre,Ord:Nombre)
LOOP
NEXT(Ordenes)
!... Proceso
END

Esto genera el siguiente SQL

www.templatesclarion.com.ar

118

Curso SQL + Clarion - www.templatesclarion.com.ar

SELECT <Campos> FROM Ordenes


WHERE (Nombre >= PEREZ)
ORDER BY Nombre

1.5.15 Clarion y NULLs


Un concepto comn en las bases de datos SQL es el concepto de nulo (NULL). El
concepto de valor nulo en un campo de una tabla o una vista indica que el usuario no ha
ingresado datos a ese campo. Null significa valor no conocido para el campo. Esto es
completamente distinto que un cero o un blanco, y permite detectar y diferenciar los
campos que nunca han sido ingresados con diferencia de los que ciertamente tienen un
cero o un blanco. El lenguaje Clarion soporta el manejo de valores Nulos mediante la
utilizacin de los comandos NULL,SETNULL and SETNONULL.
En las expresiones, Null no es equivalente a un blanco o a cero. Por ende, cualquier
expresin que compare el valor del campo de una tabla (o vista) con cualquier otro valor
siempre devolver falso cuando el campo sea nulo. Este es vlido hasta cuando el valor
de ambos elementos sean NULL. Es decir que si tenemos Tabla:Campo1 = Tabla:Campo2
va a evaluar a Verdadero si y solo si ambos campos tienen valores conocidos. Si ambos
campos tienen NULL entonces esa expresin igualmente evaluar a FALSO.
Conocido = Conocido

Evala a Verdadero o a Falso

Conocido = Desconocido

Evala a Desconocido

Desconocido = Desconocido

Evala a Desconocido

Desconocido <> 10

Evala a Desconocido

1 + Desconocido

Evala a Desconocido

Las nicas excepciones a esta reglas son las operaciones booleanas que utilicen los
operadores OR y AND donde parte de la expresin es desconocida y la otra porcin
cumple con el criterio:
Desconocido OR True

Evala a Verdadero

True OR Desconocido

Evala a Verdadero

Desconocido AND False

Evala a False

False AND Desconocido

Evala a False

El soporte de valores nulos es dependiente del File Driver. La mayora de los motores de
bases de datos soportan el concepto de valores nulos, mientras que la mayora de las
bases de datos no-sql no lo soportan.
Puede usar el comando NULL() para detectar si un valor es nulo o no. Para cualquier
campo que deba permanecer nulo al escribir en la tabla, el programador deber
explcitamente setear el campo a nulo utilizando SETNULL(). Por ejemplo,
NEXT(MiTabla)
FlagMiCampo = NULL(MiCampo)
(mas cdigo)

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

119

IF FlagMiCampo AND NOT MiCampo ! si el campo era nulo y no fue modificado


SETNULL(MiCampo)
volver a setearlo a NULL
END!IF
PUT(MiTabla)

1.5.16 SQL / VIEWs


La estructura VIEW (Vista) es una estructura de datos que automticamente define dos
operaciones relacionales estndares : el PROJECT y el JOIN. Una vista tambin
automticamente filtrara (FILTER) y ordenara (ORDER) el Set de datos. El servidor de
base de datos es el que realiza las operaciones, retornando nicamente el Set datos que
la aplicacin Cliente necesita para realizar su trabajo.
Un View se definiria con un concepto similar al VIEW de SQL, partiendo de la base que a
partir de la union de varias tablas podemos crear una nueva tabla (VIEW). Los VIEWs de
Clarion se crean automaticamente a partir de las relaciones existentes en el diccionario o
joins customizados.
En teoria el mismo codigo generado a partir de un VIEW de Clarion deberia funcionar
tanto para SQL y TPS, sin efectuar ningun cambio, sin embargo existe una diferencia
importante entre ambas plataformas:
En un VIEW SQL se retornan solamente las columnas que ud. ha colocado en el
project (Por ej. en el caso de un Browse lo que figure en el "List Box Format" mas lo
informado en el "Hot Fields" del mismo) por cada tabla del View.
En un VIEW ISAM (TPS) se retornan todas las columnas por cada una de las tablas que
figura en el Join.
Esta diferencia es valida a tener en cuenta porque quizas si migramos un aplicativo de
TPS a SQL, nos vamos a encontrar que hay cosas que antes SI funcionaban y luega de
tal migracion NO.

PROJECT
Una operacin Project relacional notifica al servidor de base de datos que solamente
utilice un subgrupo de las columnas (campos) de la tabla (reduciendo el trfico). Por
ejemplo, la vista siguiente devolver solamente algunos de los campos de la tabla de
Estudiantes.
MiVista

VIEW(Estudiantes)
PROJECT(Est:Nombre,Est:Apellido,Est:CodCarrera)
END

JOIN
Un Join relacional automticamente une (Join) renglones (registros) de mltiples tablas y
los convierte en un nico resultado que el servidor retorna al Cliente. La estructura VIEW
asume que se desea realizar un LEFT OUTER JOIN ( unin que devuelve todo el Set de la
izquierda con sus uniones de la derecha . Es decir que la cantidad de registros totales del
resultado es siempre igual a la cantidad de registros de la tabla primaria). A partir del
atributo INNER es posible cambiar el modo en que se deban realizar los JOINS. Por
ejemplo, la siguiente estructura VIEW devolver todos los estudiantes con el Nombre de
la carrera que estn estudiando.

www.templatesclarion.com.ar

120

Curso SQL + Clarion - www.templatesclarion.com.ar

MiVista

VIEW(Estudiantes)
PROJECT(Est:Nombre,Est:Apellido,Est:CodCarrera)
JOIN(Car:CodCarrera,Est:CodCarrera)
PROJECT(Maj:NombreCarrera)
END
END

Al agregar el atributo INNER el Join la vista devolver solamente aquellos estudiantes


que estn anotados en alguna carrera. Aquellos que no estn anotados en ninguna
carrera no sern incluidos en la vista (Notar que en los OUTER Join si son incluidos)
MiVista VIEW(Estudiantes)
PROJECT(Est:Nombre,Est:Apellido,Est:CodCarrera)
JOIN(Car:CodCarrera,Est:CodCarrera),INNER
PROJECT(Maj:NombreCarrera)
END
END

FILTER
El atributo Filter (Filtro) en una vista permite especificar una expresin filtro para indicar
que registros quiero ver. Esto generar un WHERE en el SQL generado. Por ejemplo, la
siguiente vista solamente devolver aquellos estudiantes cuyo nombre sea Aldo.
MiVista VIEW(Estudiantes),FILTER(Est:Nombre= ``Aldo )
PROJECT(Est:Nombre,Est:Apellido,Est:CodCarrera)
END

ORDER
El atributo Order (Orden) en una vista permite especificar como debe estar ordenado el
resultado del query. Esto generar un ORDER BY en el SQL generado. Por ejemplo, la
siguiente vista devolver a los estudiantes ordenados en forma descendente por apellido
y en forma ascendente por nombre
MiVista VIEW(Estudiantes),ORDER(-Est:Apellido,+Est:Nombre)
PROJECT(Est:Nombre,Est:Apellido,Est:CodCarrera)
END
Naturalmente todos estos conceptos pueden ser combinados (usados simultneamente)
para lograr Filtrar,Ordenar,Projectar y Unir obteniendo as el resultado deseado.

1.5.17 Browses

A continuacion detallamos algunas reglas basicas que se debe conocer al momento de Configurar los p
Lo mejor seria que los browses siempre se muestren filtrados lo mas posible y por los
componentes de la clave.
Si un browse no se abre instantaneamente, entonces es que tenemos un problema... y
cuanto mas crezca esa tabla el problema va a ir en aumento.

Evitar Table Schematics complicados


En general hay que tratar de nunca enlazar mas de un nivel de tablas en el Table
Schematic.
Cuantas mas tablas mas complejo sera el JOIN que debera resolver el motor para
mostrar el browse.
Si de todas maneras hay que usar un Table Schematic complicado, entonces ver si se
www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

121

puede usar INNER en las propiedades de todas las relaciones, ya que por defecto Clarion
genera un JOIN del tipo OUTER que es mucho mas costoso de resolver.

No poner demasiados campos en el Browse


En caso que se deseen mostrar muchos datos de un cliente por ejemplo, lo mejor es
poner todos los campos en un panel al costado del browse e ir a buscar todos los datos
de esa tabla o las relacionadas que se necesiten en el metodo TakeNewSelection del
browse. De esta manera tendremos los locators y datos basicos en el browse y el resto
de la informacion en un panel que se actualizara solo cuando encuentre el registro que
estoy buscando

Hacer depuracion con volumenes de datos reales


Hay que tratar de generar siempre datos de prueba de tal manera que al probar la
funcionalidad del sistema estemos tratando con volumenes de datos que sean
representativos del volumen real.
Si no hacemos esto lo mas probable es que a nosotros todo nos funcione muy rapido,
pero en un par de meses de puesto en marcha el sistema van a haber cosas que
funcionaran demasiado lento.
Esto ademas produce un efecto domino ya que un browse lento implica que el server
esta haciendo mucho esfuerzo por resolverlo, dejando mas lento tambien los otros
procesos y otras conexiones de usuarios.

Uso de Claves Unicas


Todas las claves que se van a usar en los Browses deberian ser unicas, el problema que
podemos tener si la clave no es unica, es que el browse pierde el puntero de donde esta
posicionado y repite los registros. Esto produce un efecto sumanente confuso para el
usuario.
La primera opcion es agregar el componente de la clave como ultimo componente de la
clave duplicada. La otra opcion es poner el componente de la clave en Aditional Sort
Fields en los browses que asi lo necesiten.
Siempre que sea posible, se recomienda definir campos autonumbers en las claves
principales (PK). De esta forma es mas sencillo "unificar" aquellas claves que no son
unicas utilizadas en los browses.
Ejemplo:
Supongamos que tenemos dos claves en una tabla Clientes: Por_Codigo y
Por_Descripcion, al adicionarle el campo de clave unica (IdAutonumber) al final de la
clave estariamos unificando la misma:
Por_Codigo
Por_Descripcion

= Codigo + IdAutonumber
= Descripcion + IdAutonumber

De esta forma nos estamos asegurando que el browse va a ser muy rapido al
momento de ejecutarse el mismo.
Otro efecto anomalo de "NO Utilizar Claves Unicas" que nos puede aparecer en los
browses es la duplicacion de registros al momento de visualizarlos.

Locators Filter, no Incremental


En general toda la filosofia de Browses y Locators hay que tratar de evitarla en
aplicaciones altamente transaccionales.

www.templatesclarion.com.ar

122

Curso SQL + Clarion - www.templatesclarion.com.ar

Pero como eso es virtualmente imposible, tratemos de usar siempre locators Entry.
Si es absolutamente necesario usar Locators que se refresquen con cada tecla, entonces
es preferible Filtered que Incremental.
Tengamos en cuenta que con este tipo de Locators se prepara y ejecuta una sentencia
SQL y vuelve un conjunto de datos por cada tecla que presiona el usuario!
Usando locators Filter en sus Browses en lugar de locators Step o Incremental puede
reducir el volumen de datos enviados entre el cliente y el servidor.
Mientras los locators Step o Incremental producen trafico SQL del tipo:
SELECT campos ... WHERE CampoLocator >= "VALOR"
El subconjunto de datos retribuido es mucho mayor que en la sentencia generada por un
locator Filter:
SELECT campos ... WHERE CampoLocator LIKE VALOR*
Tener en cuenta que la sentencia LIKE es muy ineficiente si no existe un ndice por ese
campo, y que adems la mayora de los motores no soportan un LIKE sobre campos
numricos.

Fixed Thumbs y Movable Thumbs en las Barras de Desplazamiento


Por defecto, el cdigo generado por los Wizards de Clarion usan Fixed Thumbs cuando se
hace un browse de tablas SQL porque los Movable Thumbs pueden disminuir mucho la
performance en tablas SQL grandes. Por eso se recomienda usar Fixed Thumbs en los
Browses armados manualmente.
En las propiedades del List Box seleccionar Scroll Bar Behavior.
En el Scroll Bar Type seleccionar fixed Thumb.

1.5.18 SQL Advanced Tab


En Clarion6 fue introducido en el procedimiento template Browse el Tab " SQL
Advanced". Esta nueva funcionalidad puede ser utilizada para mostrar campos
calculados dentro de un browse como por ej. realizando un SUM, AVG, COUNT.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

123

La idea de este template es bastante simple: Configurar una lista de campos a ser
mostrados en el VIEW y especificar como se cargan esos campos. Con los valores
especificados arriba, el template generara el codigo SQL adecuado para cada campo.
Para ello utiliza el comando PROP:Name para sustituir un campo en la declaracion del
Select.
Ejemplo:
En un Browse quiero mostrar el total vendido por producto. En este ejemplo vamos a
utilizar la tabla Order_details de la base de datos northwind. Esta tabla tiene el detalle de
lo vendido por productos, con lo cual necesitamos hacer un SUM(TOTAL) de la misma
por productos.
Si lo hariamos desde el motor la sintaxis correcta seria:

SELECT a.ProductID, b.ProductName, SUM(a.UnitPrice * a.Quantity - a.UnitPrice * a.Quan


FROM [Order Details]
a INNER JOIN Products b ON b.ProductID = a.ProductID GROUP BY a.ProductID, b.ProductNa
Si observamos el file schematic , en este ejemplo vemos que accedemos directamente a
la tabla Order_details realizando un JOIN con products.

www.templatesclarion.com.ar

124

Curso SQL + Clarion - www.templatesclarion.com.ar

En el "list Box Format" del browse, mostramos el codigo + Nombre del Producto
(Products) y el campo de UnitPrice (Order_details).

Si observamos el tab "SQL Advanced" vamos a ver que hay 2 campos con asignaciones
de datos. La razon por la cual Ord:ProductId tiene un valor '1' es porque los mismo se

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

125

linkean con otras tablas en el Project de clarion.


La propiedad PROP:NAME conjuntamente PROP:GROUPBY y PROP:HAVING son las que
permiten a Clarion (a partir de clarion 6) extender la funcionalidad del VIEW.
Si miramos el codigo interno generado por esta consulta es el siguiente:

v{'Ord:UnitPrice', PROP:Name} = 'Sum((a.UnitPrice*a.Quantity)-((a.UnitPrice*a.Quanti


v{'Ord:ProductID', PROP:Name} = '1'
v{PROP:GroupBy} = 'b.ProductId,b.ProductName'
En la imagen de abajo visualizamos la consulta funcionando:

1.5.19 Process /Reports


Cuando se trabaja con los procedimientos de tipo Process y Reports, se le debe indicar al
motor cuales son los campos que va a necesitar trabajar. Esa lista de campos debera
colocarla en los Tab "Hot Fields ". Con TPS el registro entero esta siempre disponible, en
cambio con SQL en los Browse/procedure/report unicamente van a ser negociados con el
Motor aquellos campos que se encuentren en el VIEW generado por los procedimientos.

www.templatesclarion.com.ar

126

Curso SQL + Clarion - www.templatesclarion.com.ar

Cantidad de registros aproximado (Approximate Record Count)


Por defecto, los Templates de Clarion generan cdigo para contar el numero total de
registros a ser procesados en un report o process. Esto permite que se muestre una barra
de progreso con el porcentaje real de registros procesados sobre el total durante la
generacin del reporte. Sin embargo para tablas SQL el SELECT COUNT(*) generado
automticamente por el Driver puede ser lento si son tablas muy grandes. Por eso, se
recomienda poner un numero de registros aproximado para evitar la generacin del
SELECT COUNT (*). Ejemplo:
Abrir el dialogo Report Properties y en el campo Record Filter, poner 1 para habilitar el
Aprox. Record Count.
Otro filtro que se puede usar es ClavePrimaria > 0, en algunos casos esto puede acelerar
el reporte forzando el acceso a travs de la clave primaria.
En el campo Aprox. Record Count, poner un contador aproximado para ese reporte.
Esto har que la barra de proceso no muestre el porcentaje exacto de registros
procesados por el reporte, pero es mas rpido ya que se evita el conteo de registros por
parte del Server.

1.5.20 Transacciones Batch


La mayora de las bases de datos SQL operan en modo auto commit. Esto significa que
cualquier operacin que actualice la tabla (ADD, PUT, DELETE) ejecuta un COMMIT
implcito. Esto puede ser muy lento para actualizaciones en lotes o masivas (batch).
Para optimizarlo podemos encerrar todo el procesamiento en una transaccin, esto es
entre un LOGIN y un COMMIT.
Ejemplo:
LOGOUT(.1,OrderDetail) !Begin Transaction
DO ErrHandler !Siempre chequear errores
LOOP X# = 1 TO RECORDS(DetailQue) !Procesar los registros de una cola
GET(DetailQue,X#) !Traigo el registro de la cola
DO ErrHandler !Errores?
Det:Record = DetailQue !Asigno el record Buffer
ADD(OrderDetail) !y lo agrego al archivo
DO ErrHandler !Errores?
END
COMMIT !Termino la transaccion sin problemas

ErrHandler ROUTINE !Error routine


IF NOT ERRORCODE() THEN EXIT. !Todo OK, continua
ROLLBACK !Si hubo un problema entonces deshago la transaccion
MESSAGE(Error en la Transaccion - & ERROR())
RETURN 884

1.5.21 Manejo de Transacciones


El comando LOGOUT() realiza el comienzo transaccional para un conjunto especificado de
archivos. El LOGOUT() le informa al file driver que una transaccin est comenzando y al
mismo se encarga que los archivos sean bloqueados para el tratamiento transaccional.
Solamente un LOGOUT() puede estar activo a la vez; un segundo LOGOUT() sin un
anterior COMMIT o ROLLBACK genera el errorcode() = 56.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

127

Siempre que agregamos o modificamos datos dentro de un LOGOUT estos datos quedan
Lockeados. Si algun browse o reporte intenta leer estos datos va a quedar colgado.Por
esto las transacciones deben ser siempre lo mas cortas posible. Nunca se debe dejar una
transaccion abierta con algun mensaje o intervencion pendiente del usuario.
Un ejemplo claro de mala practica es iniciar una transaccion (LOGOUT) en el Init de una
carga de cabecera / detalle, un COMMIT en el TakeCompleted y un ROLLBACK en el
Cancel. Todos los registros que se agreguen estan lockeados hasta que el usuario no se
decida, generando lockeos con otras terminales.
Lo que debe hacerse es trabajar todo en memoria o tablas auxiliares y confirmar todo el
procesamiento transaccional en el minimo tiempo posible (generalmente en el
TakeCompleted).

1.5.22 Stored Procedures


Hay tres caminos principales de comunicacion con una base de datos de Microsoft SQL usando
Clarion:
1. Permitiendo que los templates y el lenguaje Clarion trabaje por nosotros.
2. Usando PROP:SQL en determinados embebidos enviando el codigo SQL directamente.
3. Usando PROP:SQL con un Stored Procedure.
Un stored procedure es un programa (o funcin) el cual est fsicamente almacenado en
una base de datos. La ventaja de un stored procedure es que cuando est en accin, en
respuesta a una peticin de usuario, corre directamente en el motor de bases de datos,
aumentando con ello generalmente, la rapidez de proceso.
No Solamente un programa Clarion puede acceder a un stored procedure, sino que se
pueden acceder desde otr aplicativo o desde un editor de SQL.
Desde Clarion hay dos formas de ejecutar un Stored Procedure:

1) Llamando a un stored que nos devuelve un pool de datos:


Ejemplo:

Loc:Query = 'CALL sp_Nombre_Store('&Parametro1&' ,'&Parametro&')'


ResSQL{prop:sql} = Loc:Query

!! enviamos el query al Motor

IF FILEERRORCODE() !! mapeamos el error


SETCLIPBOARD(Loc:query) !! colocamos al Clipboard el query por si queremos ejecutarlo de
MESSAGE('Atencion Ocurrio un error ='&FILEERROR(),'ERROR',ICON:HAND)
ELSE
LOOP Until Access:ResSQL.Next()
!! Procesamos los datos devueltos por el stored Procedure

END
END
2) Llamando a un stored que no devuelve datos :

www.templatesclarion.com.ar

128

Curso SQL + Clarion - www.templatesclarion.com.ar

Ejemplo:

Loc:Query = 'NORESULTCALL sp_Nombre_Store('&Parametro1&' ,'&Parametro&')'


ResSQL{prop:sql} = Loc:Query

!! enviamos el query al Motor

IF FILEERRORCODE() !! mapeamos el error


SETCLIPBOARD(Loc:query) !! colocamos al Clipboard el query por si queremos ejecutarlo de
MESSAGE('Atencion Ocurrio un error ='&FILEERROR(),'ERROR',ICON:HAND)
END

1.5.23 Usando TurboSQL


Desde Clarion 6.3 en adelante, los drivers SQL (excepto Oracle) soportan el driver string
/TURBOSQL. Si esta seteado en TRUE, el driver no verificara que todas las columnas
existan en el server al hacer el OPEN.
Es decir, que el driver no verifica que la estructura de la tabla definida en el dct coincida
con la estructura de la tabla fisica, razon por la cual nunca se va a dar el error "invalid
record declaration".
Se puede usar este driver string para declarar un buffer en la aplicacion para recibir los
resultados de las ejecuciones de prop:sql sin la necesidad de definir una tabla
exactamente igual en el motor SQL.
Es muy util tambien para los casos en los que no tenemos acceso del tipo administrativo
al motor SQL y/o no podemos acceder a modificar la estructura de las tablas definidas.
Una de las cosas a tener en cuenta al utilizar esta propiedad, es que debemos tener
sumo cuidado con el control de errores. Si el sistema asume la existencia de una
columna que fue eliminada en el motor, es probable que esto provoque la caida del
sistema o nos emita un "GPF" (Error de Windows).
Otra de las cosas a tener en cuenta es que esta propiedad esta pensada para los casos
en donde se reciben resultados desde sentencias PROP:SQL enviadas al motor. Por lo
tanto no es aconsejable utilizarlo en tablas que requieran actualizaciones.
Para setearlo puede hacerlo desde el diccionario poniendo '/TURBOSQL=1' en 'Driver
Options' o en por source con el comando SEND

1.5.24 Uso del trace


Usar el trace
Siempre que tengamos una duda de que esta pasando el programa
\Clarion6\bin\trace.exe nos puede ser de gran ayuda para mostranos exactamente lo que
le esta llegando al motor, como estan los datos del buffer , etc..
Esta utilidad genera un archivo log con informacion que es muy importante a modo de
debug, acerca del dilogo que se esta llevando a cabo entre el driver y el motor de base
de datos (como por ejemplo los queries sql generados, los codigos devueltos, etc) o
tambien con cualquier otro tipo de archivo (isam, ado, etc)

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

129

A continuacion vamos a ver un ejemplo con el driver ODBC:

Estas opciones se almacenan en el archivo WIN.INI, siendo para este ejemplo los
siguientes valores:
[CWODBC]
Trace=1
TraceFile=c:\temp\log_fb_test_01.txt
Profile=1
Details=1
Flush=1
Profile=1 (Show Clarion Statements) indica que se debe incluir informacin respecto
de los comandos de Clarion sobre la lectura/escritura de archivos
Details=1 (Show record buffer contents) indica que se debe incluir informacin
sobre el contenido de los registros (buffers) de los archivos. Slo se habilita si Profile=1
. En caso de que el archivo se encuentre encriptado, para poder ver el contenido del
registro tambin hace falta activar la propiedad PROP:AllowDetails sobre el driver
('/ALLOWDETAILS =TRUE' )
Trace=1 (Trace calls to back end) indica que se debe incluir informacin sobre el
cdigo sql generado hacia el motor, con su correspondiente cdigo de retorno desde el
motor
En File to store tracing in (TraceFile) se indica el nombre del archivo que se va a
generar; si desea redireccionar la informacin generada hacia el debug, debe tipear la
palabra reservada DEBUG

El siguiente es un fragmento de un archivo log generado con Profile=1:


05BCH(2) 19:57:13.326 QUERY_KEY(COUNTRY:016AAA8H) Time Taken:0.00 secs
05BCH(2) 19:57:13.326 BUFFER(COUNTRY:016AAA8H) Time Taken:0.00 secs

www.templatesclarion.com.ar

130

Curso SQL + Clarion - www.templatesclarion.com.ar

05BCH(2) 19:57:13.326
05BCH(2) 19:57:13.326
Taken:0.00 secs
05BCH(2) 19:57:13.326
Taken:0.00 secs
05BCH(2) 19:57:13.326
secs
05BCH(2) 19:57:13.326
Taken:0.00 secs
05BCH(2) 19:57:13.326
Taken:0.00 secs
05BCH(2) 19:57:13.346
secs
05BCH(2) 19:57:13.346
05BCH(2) 19:57:13.346
05BCH(2) 19:57:13.346
Taken:0.00 secs
05BCH(2) 19:57:13.346
secs
05BCH(2) 19:57:13.346
05BCH(2) 19:57:13.346
05BCH(2) 19:57:13.346
Taken:0.00 secs
05BCH(2) 19:57:13.346
secs
05BCH(2) 19:57:13.346
05BCH(2) 19:57:13.346

QUERY_KEY(COUNTRY:016AAA8H) Time Taken:0.00 secs


GET_PROPERTY(VIEW:187AB8:COUNTRY:0187A68H) Time
GET_PROPERTY(VIEW:187AB8:COUNTRY:0187A68H)
BUFFER(VIEW:187AB8:COUNTRY:0187A68H)

Time Taken:0.00

SET_PROPERTY(VIEW:187AB8:COUNTRY:0187A68H)
SETview(VIEW:187AB8:COUNTRY:0187A68H)
NEXT(VIEW:187AB8:COUNTRY:0187A68H)

Time Taken:0.02

Time

Time Taken:0.00

COU:COUNTRY : 'Austria'
COU:CURRENCY : 'Schilling'
POSITIONfile(VIEW:187AB8:COUNTRY:0187A68H)
NEXT(VIEW:187AB8:COUNTRY:0187A68H)

Time

Time

COU:COUNTRY : 'Australia'
COU:CURRENCY : 'ADollar'
POSITIONfile(VIEW:187AB8:COUNTRY:0187A68H)
NEXT(VIEW:187AB8:COUNTRY:0187A68H)

Time

Time

Time Taken:0.00

COU:COUNTRY : 'Belgium'
COU:CURRENCY : 'BFranc'

El siguiente es un fragmento de un archivo log generado con Trace=1:


0B18H(2) 19:46:57.962 Setting Cursor Type to Forward Only for Statement 0C72498H
Time Taken:0.00 secs
0B18H(2) 19:46:57.962 Resetting Parameters Statement 0C72498H Time Taken:0.00
secs
0B18H(2) 19:46:57.962 Preparing Statement 0C72498H : SELECT A.COUNTRY,
A.CURRENCY FROM COUNTRY A ORDER BY A.COUNTRY Time Taken:0.02 secs

Importante: no se olvide de apagar el trace manualmente, ya que el mismo no se


apaga automaticamente al cerrar la ventana (si queda encendido se dara cuenta porque
la aplicacion corre mas lenta)

Ademas del trace tradicional mediante la pantalla que hemos detallado, tambin se
puede controlar la informacin de manera condicional, mediante el uso de propiedades
enviadas al driver
Por ejemplo:
SYSTEM{PROP:DriverTracing} = ''
SYSTEM{PROP:DriverTracing} = '1'
tabla{PROP:Profile}=Pathname

www.templatesclarion.com.ar

!desactiva el log para todos los drivers


!activa el log nuevamente
!setea Profile=1

Programando con CLARION + SQL (MS-SQL)

tabla{PROP:Profile}=''
LOC:Nombre = tabla{PROP:Profile}
tabla{PROP:Log}='test'
tabla{PROP:Details}=1
tabla{PROP:Details}=0

131

!setea Profile=0
!consulta el nombre del archivo log
!escribe el 'test' en el archivo log
!setea Details=1
!setea Details=0

1.5.25 Cargas de Cabecera - Detalle


Este es un tema que siempre se presta a discusiones en todos los cursos.
Hay muchas formas de resolverlo, pero les voy a hacer un resumen de cual es la manera
mejor y mas facil que he encontrado.

Puntos a tener en cuenta


Supongamos que vamos a cargar comprobantes, Facturas por ejemplo. No vamos a usar
autonumeracion de Clarion para la tabla Facturas.
Generacion del Numero de Transaccion
Al abrir el Form de Facturas genero un nro unico que identifique esta transaccion, se
puede hacer de varias maneras, como ya se explico en el tema "Campos
autonumerados".

Carga del Detalle


El detalle lo cargo en una tabla auxiliar. Tambien podria hacerse en un Queue pero en
general es mas complicado.
La ventaja de usar un DetalleAUX es que se usa direcamente un browse con ABM o EIP,
como siempre.
Tambien puede usarse el In Memory Driver para esta carga, y de hecho es ideal para
eso.
El browse de DetalleAUX lo filtro (rango) por el NroTransaccion y obviamente este dato lo
uso como enganche entre la cabecera y DetalleAUX. Cada nuevo registro en DetalleAUX
le asigno este NroTransaccion.
Confirmacion de la Transaccion
En el Take Completed, antes del Parent Call:
- abro una transaccion
- calculo el Numero oficial del comprobante, mediante una tabla de numeraciones.
- inserto la cabecera
- muevo todos los registros desde DetalleAux a la tabla real de Detalle (borrando
DetalleAUX)
- cierro la transaccion
Esto seria ideal hacerlo en un Stored Procedure ya que tendriamos mejor control de la
transaccion y seria mucho mas rapido.
Importante: Recuerden que todo el tiempo que este la transaccion abierta estamos
provocando lockeos que pueden afectar browses o reportes que trabajen sobre la tabla
facturas.
En el Cancel borro los registros de la transaccion en DetalleAux.

www.templatesclarion.com.ar

132

Curso SQL + Clarion - www.templatesclarion.com.ar

Si hay colgadas, puede ir quedando basura (inofensiva) en la tabla DetalleAux, la cual


seria bueno borrar cada tanto.
La tabla DetalleAux debe identificar el usuario en una columna, o bien crear una nueva
tabla temporal por cada usuario. Lo mas aconsejable es el In-Memory Driver

1.5.26 Creando un Editor de SQL

Apliquemos lo anterior para crear un editor de SQL sencillo.


Primero necesitamos crear un Diccionario con la variable Global de conexin.(tambien
podria estar en el app, claro)

Y la tabla SQL. En este caso crearemos solo 5 campos

Recordemos que siempre se debe usar un String de conexin variable en el Owner de las
tablas.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

Creamos un app con este DCT

www.templatesclarion.com.ar

133

134

Curso SQL + Clarion - www.templatesclarion.com.ar

En global Embeds Program setup inicializamos el String de Conexin.


En este caso desde un INI, pero tambien se podria llamar a una simple pantalla de
conexin que nos pida los datos de server, base, usuario y pasword.

Para simplificar el ejemplo usaremos codigo basico CLARION, no ABC. Por lo tanto
deshabilitamos el Defer Open Files.
Si no lo hicieramos, la tabla SQL podria no estar abierta cuando quisieramos recorrerla
con NEXT.
(En general yo siempre deshabilito ese check.)

Creamos una ventana para nuestro procedimiento principal.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

Elegimos Simple Window, sera la mas indicada en este caso.

www.templatesclarion.com.ar

135

136

Curso SQL + Clarion - www.templatesclarion.com.ar

En el Table Schematic agregamos nuestra tabla SQL

En Local Data definiremos una variable TextoSQL donde poder escribir las sentencias SQL
a ejecutar y una cola de memoria donde vamos a guardar los resultados.
A los campos de la cola de memoria le ponemos los mismos nombres que a la tabla SQL
para poder hacer directamente una asignacion profunda :=:

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

Diseamos una pantalla con este formato

www.templatesclarion.com.ar

137

138

Curso SQL + Clarion - www.templatesclarion.com.ar

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

139

Creamos un control listbox, NO un template browse.


Elegimos los campos de la cola de memoria en el mismo orden.
(Tambien podriamos usar el atributo Field Number si quisieramos cambiar el orden de los
campos en el list, pero en este caso no tiene sentido)

www.templatesclarion.com.ar

140

Curso SQL + Clarion - www.templatesclarion.com.ar

No olvidarse de setear la propiedad From del List

Este es todo el codigo que va en el Boton.


En SQL usamos siempre FileError() en vez de Error(). FileError() devuelve el error
detallado que reporta el motor SQL.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

Ya tenemos nuestro propio Editor SQL!

1.6

Links - Material Recomendado


In-Memory Database Driver

www.templatesclarion.com.ar

141

142

Curso SQL + Clarion - www.templatesclarion.com.ar

Microsoft - SQL Server


http://www.mug.org.ar
Libros en Pantalla
Funciones SQL
http://www.mssqltips.com
http://www.programacion.com
Clarion Magazine publicacion de Dave Harms. Muy buen recurso CLARION
SQL Server Magazine
http://sqlzoo.net/
Strings de Conexion
icetips
Productos Templates Clarion

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

143

Ejemplos

1.6.1

In-Memory Database Driver


SoftVelocity ha desarrollado un driver de archivos que nos permite utilizar la misma
tecnologa de los drivers de Clarion para el acceso a base de datos, pero utilizando tablas
"en memoria" (In-Memory driver o IMDD). Esto significa que podemos utilizar los mismos
comandos con los que estamos familiarizados para acceder y actualizar tablas con
cualquier otro driver de archivos. Los datos seran almacenados en memoria RAM, lo que
nos brinda una serie de ventajas.
Soporta la suma de tipos de datos de todos los drivers de archivos. Elimina el uso de
tablas temporales. Se puede utilizar el comando copy para duplicar tablas en memoria de
manera instantanea. Es compatible con cualquier template o producto de terceras partes
En aplicaciones SQL se puede utilizar como buffer para recibir el resultado de los queries
sql. Una vez que la tabla en memoria recibe el conjunto de datos se pueden aplicar
ordenamientos, filtros, queries QBE/QBF y dems utilizando los comandos y
procedimientos estandar de Clarion (por ejemplo Browse). Esto reduciria notablemente el
trafico en la red y los recursos del servidor.

1.6.2

Ejemplos
El curso de SQL, cuenta con dos ejemplo de Clarion (App/Dct) . Los mismos fueron
desarrollados en Clarion6 cuyo dct se realizaron importando la Base Northwind del Motor
MS-SQL a un dct.
Luego de la instalacion del manual, se encuentran ubicados en el sub-directorio
"ejemplos" del directorio de instalacion del mismo (por defecto: "C:\ClarionCursoSQL")

Northwind.app
Este app contiene ejemplos de:

Uso de SQL Advanced Tab

Aplicacion de Uso de SQL Advanced Tab en un Reporte

Uso de Identity en Clarion

Uso de Prop:Where

www.templatesclarion.com.ar

144

Curso SQL + Clarion - www.templatesclarion.com.ar

Uso de queues y filtros con fechas

Uso de Stored Procedures.

sqlEditor.app
Este app contiene el ejemplo del Editor de sql.

www.templatesclarion.com.ar

Programando con CLARION + SQL (MS-SQL)

www.templatesclarion.com.ar

145

Index

Integridad 92
Integridad de los datos

Index

-K-

-A-

Keys

Advanced Tab
Archivos 85

-LLogin

Batch 126
Browses Lentos?
BUFFER 111

91

122

-B-

Campos Date 113


Cargas de Cabecera - Detalle
Clarion vs. SQL 116
Claves 91
Conexion 100
Consultas 58
creacion 93
CSTRING x STRING 104

108

-M-

120

Manejo Fechas 104


Manipulacin de Datos
Migracion 105

-C131

-NNext 117
Normalizacin
Nulls 118

ODBC 102
Owner Name

Database Driver 101


Definicin de datos 30
DTS 13

-P-

-EEditor SQL 132


Errores 117
External Name 87

100

Previous 117
Process 125
Prop:SQL 109
Prop:SQLFilter 111
Prop:Where 112
Propiedades 85

-R-

-F51

-IIndices

16

-O-

-D-

fecha

24

91

www.templatesclarion.com.ar

Recomendaciones
Relaciones 92
Reports 125

106

31

147

148

Curso SQL + Clarion - www.templatesclarion.com.ar

-SSet 117
SetFilter + SQL 113
sintaxis de Transact-SQL
SQL 122
SQL Embebido 109
SQLIdentity 90
Stored Procedures 127
Stupid table 114
Subconsultas 64

53

-TTabla Boba 114


Tablas 93
Tipos datos 26
Tipos de Datos 87
Tps a SQL 102
Trace 128
Transacciones 77, 126
Turbo SQL 128

-VValidacion 108
VIEW 119

www.templatesclarion.com.ar

Potrebbero piacerti anche