Anda di halaman 1dari 38

SQL

scar Javier Segura Amors


oscarjsa@hotmail.com

Cedida su publicacin a el Rinconcito de Delphi

No est autorizada su reproduccin sin permiso expreso de su autor

SQL. El lenguaje universal de las Bases de Datos.


scar Javier Segura Amors - oscarjsa@hotmail.com

Vamos a conocer SQL, un lenguaje de definicin y manipulacin utilizado por todas las grandes Bases de Datos.
SQL (Standard Query Language, Lenguaje de consultas estndar o estructurado), es un lenguaje que nos permitir operar con nuestras bases de datos de una forma sencilla y potente. Se encuentra muy difundido y es soportado por todos los grandes sistemas gestores de bases de datos como pueden ser: Oracle, Interbase, Microsoft, Informix, Sybase, etc. La gran ventaja que nos ofrece SQL frente a otras formas de trabajar es su estandarizacin, no es necesario que cuando nos encontramos ante diferentes sistemas gestores tengamos que aprender como funciona cada uno de ellos de una forma ms o menos detallada, simplemente debemos conocer como se trabaja con SQL, ya que su sintaxis y estructuracin sufre muy pocas variaciones de un sistema otro. Por lo tanto SQL nos ofrece una nica forma de trabajar con independencia del sistema con el que tengamos que hacerlo, con el consiguiente ahorro de tiempo y energas por parte de programador. Para comenzar a entender las grandes virtudes que tiene SQL y las interesantes facilidades y posibilidades que nos brinda, vamos a imaginar la siguiente situacin. Imaginemos que hemos diseado una base de datos para un grupo de clientes. El diseo de sta, lgicamente, debe de ser independiente del sistema gestor en el que vaya a funcionar, pero qu ocurre cuando llegamos al cliente con el diseo hecho y tenemos que montarlo. Si tenemos la suerte de conocer el sistema gestor que el cliente utiliza, no tenemos ningn problema, pero qu pasa cuando no lo conocemos, perdemos mucho tiempo. Adems, si la misma base de datos la vamos a montar para diferentes clientes, lo normal es que nos encontremos con diferentes gestores. Pues este inconveniente, que en principio para el programador puede ser un problema, SQL nos lo resuelve. Si conocemos SQL, podremos llegar al cliente con los scrips de SQL en los que tenemos ya escritos todas las sentencias necesarias para: crear la base de datos, crear todas las tablas y relaciones, todos los tipos de datos de las tablas, todas las reglas de validacin y las consultas para informes, solamente nos restar ejecutar esos scrips en el servidor y trabajo finalizado. Qu hemos conseguido? Hemos conseguido rapidez, eficiencia, que el cliente quede satisfecho y nos hemos ahorrado interminables momentos de problemas porque el sistema gestor que utiliza el cliente no terminamos de conocerlo muy bien. Qu maravilloso, verdad?. Bienvenidos a SQL. Un poco de historia. SQL comenz a ver la luz sobre el final de la dcada de los 70, implementado como un prototipo por IBM y en 1979 aparece el primer sistema gestor de bases de datos que lo soporta, Oracle. Poco tiempo despus, otros sistemas como DB2, Interbase, etc, tambin quisieron adoptar al nuevo recin nacido. Ya en 1987, 1992, 1995, 1996 se le confiri la estandarizacin a travs de las normas ISO, hasta la actualidad, en la que todo sistema SQL se basa en el estndar SQL-3 (ISO-99) en el que se le han aadido nuevas caractersticas como la creacin de TADs (tipos abstractos de datos), reglas activas (triggers disparadores), cursores sensitivos, operador de unin recursiva, etc. Aunque todo el SQL est estandarizado, s es cierto que encontramos pequeas diferencias en la sintaxis de las sentencias en los diferentes sistemas gestores. Estas diferencias repito que son mnimas y una vez realizados los scrips de SQL que, por ejemplo, disean una base de datos, tendremos que hacer muy pocas variaciones si queremos que esos scrips se ejecuten en diferentes sistemas gestores Emplazo al lector para siguientes artculos en los que abordar las diferencias ms notables entre los principales sistemas gestores de bases de datos SQL, en los que tratar de orientarlo sobre la variaciones sintcticas con las que nos vamos a encontrar. Insisto de nuevo en que esas diferencias son mnimas, tan mnimas que no llegan a ser un inconveniente para la utilizacin de SQL.

Funcionamiento de las bases de datos SQL


Siempre que realicemos un aplicacin que vaya a trabajar sobre una base de datos, sta la situaremos dentro de un servidor de base de datos. El servidor puede ser una mquina dedicada, cuya nica funcin sea la de atender peticiones de sus clientes, devolvindoles la informacin y ejecutando los procedimientos ordenados por estos sobre la base de datos. O tambin el servidor puede ser la misma mquina sobre la que corra la propia aplicacin. Depender ya de la estructura e importancia del sistema informtico sobre el que vaya a funcionar nuestra aplicacin. Sea cual sea la frmula que vayamos a utilizar, la forma de trabajar ser la misma, la nica diferencia ser si trabajamos con un solo ordenador, que har simultneamente las funciones de servidor y cliente, o con una red de ordenadores en la que los clientes y el servidor, en principio, quedan definidos de una forma ms clara. Una vez que conocemos como se estructura una base de datos SQL vamos a ver, a grandes rasgos, cmo funciona, cmo se realiza la comunicacin entre el servidor y el cliente. Vamos a verlo muy por encima, sin entrar en detalles, simplemente para entender la forma de trabajar. El cliente tendr instalado un cliente SQL y el servidor tendr instalado un servidor de SQL. La base de datos estar instalada en el servidor y ser nicamente el servidor de SQL el que acceda a sta. Cuando nuestra aplicacin realice una llamada a una sentencia SQL no ser ella quien la ejecute. Esa sentencia llamar al cliente de SQL que tenemos instalado en nuestra mquina y ser l quien se ponga en comunicacin con el servidor de SQL. Una vez que el servidor SQL ha recibido la peticin del cliente la ejecutar sobre la base de datos, y el resultado de la ejecucin ser devuelta al cliente que se la pasar a la aplicacin. Es el funcionamiento clsico de una distribucin cliente-servidor. No es el momento de ensalzar las virtudes que tiene esta forma de trabajar, simplemente comentar que tiene el inconveniente de la rapidez, es lgico que el tiempo que se necesita para realizar todo el proceso desde que la aplicacin realiza la llamada al cliente con la sentencia SQL hasta que ste le devuelve los datos, es mayor que si la aplicacin trabajara directamente con la base de datos, de todas formas tampoco quiero dar la impresin de que el retardo de tiempo es importante, porque es mnimo. Pero en contraposicin encontramos muchas ventajas, sobre todo cuando van a ser varios los usuarios que utilizando simultneamente nuestra aplicacin trabajen con la base de datos, ventajas como: la integridad de los datos, la recuperacin ante fallos, las inevitables colisiones, las transacciones, etc.

Las instrucciones de SQL


Las instrucciones de SQL las podemos dividir en dos grandes grupos: las instrucciones que trabajan con la estructura de los datos, Lenguaje de definicin de datos (LDD), y las instrucciones que trabajan con los datos en s, Lenguaje de manipulacin de datos (LMD). El lenguaje de definicin de datos nos permitir: crear nuestra base de datos, los tipos de datos definidos por el usuario, las tablas, las reglas de validacin de los datos y las relaciones. El lenguaje de manipulacin de datos nos permitir: introducir, modificar y borrar datos, realizar consultas y definir nuestros procedimientos y triggers o disparadores. Como podemos apreciar, tenemos aun mucho trabajo por delante, pero prometo que va a valer la pena el esfuerzo. Comenzaremos conociendo las instrucciones de definicin de datos y continuaremos viendo las de manipulacin. Para hacer ms fcil el aprendizaje vamos a trabajar sobre una hipottica base de datos. Una base de datos sencilla que nos va a permitir reflejar las explicaciones que se realicen sobre SQL en un ejemplo prctico. Este ejemplo lo iremos intercalando con otros pequeos ejemplos no relacionados con l, que sirvan para completar el lado prctico del aprendizaje. A lo largo del presente artculo conoceremos las instrucciones de definicin de datos, dejando para el prximo las instrucciones de manipulacin de esos datos. De todas formas, al final de esta entrega daremos una pequea pincelada a las instrucciones de manipulacin para que el lector vaya introducindose un poco en ellas y nos sirva de cierto avance o introduccin para la parte de SQL, que de momento, nos vamos a quedar sin conocer.

Diseo de una base de datos


Aunque no es estrictamente el tema de este artculo voy a nombrar brevemente los pasos que debemos seguir cuando vamos a disear una base de datos. De la misma forma que ya he hecho anteriormente, vuelvo a emplazar al lector para siguientes artculos donde trataremos este tema con mucha ms profundidad. Cuando nos enfrentamos al diseo de una base de datos muchos programadores se lanzan directamente al interfaz del sistema gestor a comenzar a introducir tablas, atributos y relaciones. Gran error, aunque nos encontremos en la era de las nuevas tecnologas debemos todava comenzar nuestro trabajo con unos folios en blanco y un lpiz, mejor gastar un poco de tiempo al principio que desesperarnos cuando estamos terminando el trabajo porque nos hemos dado cuenta que tenemos errores de diseo, normalmente estos errores son muy difciles de solucionar, cuando al no detectarlos previamente hemos basado todo nuestro diseo y trabajo sobre ellos. Cuando tenemos que realizar el diseo de una base de datos comenzaremos por reunirnos con el cliente y que nos especifique con todo detalle como funciona el sistema que tenemos que informatizar. Esa reunin la tendremos que repetir cuantas veces sea necesaria hasta que conozcamos perfectamente la problemtica que tenemos que resolver. Una vez conozcamos perfectamente el sistema comenzaremos a disearnos sobre papel el esquema lgico de nuestra base de datos. Existen muchas modelados para representar la realidad que queremos informatizar, aunque el ms conocido y extendido es el Entidad Relacin Extendido (EER). No se trata mas que de una forma de representar nuestra base de datos a travs de un dibujo, de forma que podemos identificar rpidamente todos los componentes de la misma. En la Figura 1 podemos ver el EER de nuestra base de datos.

Figura 1. Modelo lgico, esquema ERR, de nuestra base de datos de ejemplo, Facturacin. Una vez tenemos diseada nuestra base de datos, utilizando por ejemplo el modelo EER, obtendremos de l las tablas, campos de cada una de ellas y relaciones. Al obtener los elementos de la base de datos del esquema lgico nos aseguramos una metodologa, un formalismo y evitamos los errores de diseo tpicos que siempre aparecen cuando estos se realizan de forma intuitiva. Una vez que ya tenemos las tablas, sus campos y relaciones, ya podemos con SQL generar las instrucciones de los scrips de creacin y manipulacin de la base de datos.

Base de datos Facturacin


Del EER de nuestra base de datos Facturacin obtenemos las siguientes tablas, campos y relaciones. Tabla Clientes:

DNI Nombre Direccion Ciudad CodigoPostal Telefono

Caracter(9) (Clave Primaria) CaracterVariable(50) CaracterVariable(60) CaracterVariable(30) Caracter(5) Caracter(9)

Tabla Facturas

Numero Fecha Total DNI

Entero (Clave Primaria) Fecha Flotante Caracter(9) (Clave Ajena hacia Clientes)

Tabla LineasFactura

Numero Factura Cantidad Articulo Precio Total

Autoincremento (Clave Primaria) Entero (Clave Ajena hacia Facturas) Valor no nulo Entero Entero (Clave Ajena hacia Articulos) Valor no nulo Flotante Flotante

Tabla Articulos

Codigo Nombre PrecioCompra IVA

Entero (Clave Primaria) CaracterVariable(40) Flotante Flotante

La Clave Ajena hace referencia a que el dato de ese campo deben o ser nulos, si es permitido que lo sea, o existir en la tabla a la que hace referencia dicho campo. Esta regla es conocida como la regla de la integridad referencial. El concepto de Clave Primaria significa que el valor de dicho campo sirve de valor de identificacin de ese registro dentro de la tabla, de forma que el dato en l introducido no puede ser nulo ni estar repetido en otro registro de la misma tabla. En la tabla Clientes su Clave Primaria es el DNI (Documento Nacional de Identidad) porque todos los clientes son personas y por lo tanto todos tienen que tener un DNI, primera condicin de la Clave Primaria, nunca puede ser nula, y adems el DNI no se va a repetir nunca puesto que no existen dos iguales, segunda condicin de la Clave Primaria.

El campo Total de la tabla Facturas se refiere al total de la factura. El campo Total de la tabla LineasFactura se refiere al total de cada una de las lneas. Ambos datos son del tipo flotante pensando en que la facturacin que intentamos hacer va enfoca al Euro. Como el Euro tiene dos posiciones decimales nos es necesario asignarle un flotante. En la tabla Artculos el campo IVA (Impuesto sobre el Valor Aadido) hace referencia a este impuesto que cada uno de los artculos llevar. El dato del IVA es un porcentaje sobre el precio del artculo. Si nos fijamos ya tenemos definidas las tablas, los campos de dichas tablas, junto con sus tipos de datos y las relaciones que existen entre las diferentes tablas. Las relaciones las tenemos plasmadas a travs de los campos de Clave Ajena que nos indican con que tabla estar relacionado el campo que sufre la clave. Los campos que llevan la caracterstica de Valor no nulo nunca pueden dejarse en blanco. Si nos fijamos, estos campos son Claves Ajenas, por lo tanto lo que estamos consiguiendo es obligando a que siempre exista la relacin, es decir, si existe un registro en la tabla, este registro estar obligado a relacionarse con la otra tabla, porque el campo que sirve para relacionar ambas tablas nunca puede estar en blanco.

Convenciones de diseo y algn consejo previo


Voy a citar las normas de diseo que debemos seguir para trabajar con las bases de datos de SQL y algn consejo que siempre nos vendr bien seguir. En el desarrollo de los siguientes apartados utilizar la notacin estndar que describo a continuacin:

MAYSCULAS Palabras clave de Transact-SQL. Cursiva Parmetros de la sintaxis de Transact-SQL. | (barra vertical) Separa los elementos de sintaxis con corchetes o llaves. Slo se puede elegir uno de los elementos. [ ] (corchetes) Elementos de sintaxis opcionales. No escriba los corchetes. { } (llaves) Elementos de sintaxis requeridos. No escriba las llaves. [,...n] Indica que el elemento anterior se puede repetir n veces. Los elementos se separan mediante comas. [ ...n] Indica que el elemento anterior se puede repetir n veces. Los elementos se separan mediante espacios en blanco. Negrita Nombre de bases de datos, tablas, ndices, procedimientos almacenados, programas, tipos de datos y texto que deben escribirse exactamente como se muestra.

En el nombre de la base de datos, de una tabla, de una regla o de un tipo definido por el usuario, es decir en los elementos que el usuario crea y que por lo tanto debe de nombrar, no se pueden introducir espacios en blanco, lo normal es sustituir esos espacios en blanco por el carcter de subrayado ,'_', o comenzar la siguiente palabra por una letra mayscula. Ejemplo: Lineas Pedido, sera incorrecto, podramos nombrar esta tabla como Lineas_Pedido,o LineasPedido. A lo largo del artculo yo utilizar cualquiera de las dos formas indistintamente, aunque lo adecuado es que se elija una forma y se mantenga durante todo el trabajo. Para definir los CONSTRAINT, elemento que abordaremos ms tarde, si define una clave primaria el nombre de esta tendr la forma cp_nombre_tabla, si se trata de una clave alternativa su nombre ser cal_nombre_tabla y si se trata de una clave ajena caj_nombre_tabla. Si existiera dentro de la misma tabla ms de una clave del mismo tipo iran numeradas, cp_nombre_tabla1, cp_nombre_tabla2, ... .

Crear, conectarse y borrar una base de datos (CREATE DATABASE, CONNECT DATABASE, DROP DATABASE)
Cuando comenzamos a crear nuestra base de datos en el servidor, el primer paso del montaje es crear la base de datos. Hasta que no creamos la base de datos no podemos comenzar a crear las tablas y dems elementos. La creacin de la base de datos se har una nica vez. Normalmente el proceso de creacin se hace desde el entorno visual del sistema gestor pero no existe ningn inconveniente en hacerlo utilizando comandos SQL. Si lo hacemos desde SQL el comando de creacin es CREATE DATABASE, y su sintaxis:
CREATE DATABASE nombre_base_datos

La sintaxis de CREATE DATABASE admite muchos ms parmetros aunque normalmente no se utilizan. En los sistemas gestores a la hora de crear nuestra base de datos debemos de estar situados en la base de datos del sistema, en la mayora de los sistemas llamada master. Esto es as porque en ella se introducir la informacin de las propiedades de nuestra base de datos, la que terminamos de crear. Una vez que hemos creado nuestra base de datos, proceso que debemos realizar solamente la primera vez, cada vez que queramos trabajar con ella tendremos que establecer la conexin entre nuestro cliente de SQL y el servidor de SQL. Este proceso, al igual que el proceso de creacin, se suele realizar desde el interfaz grfico. Normalmente el sistema gestor nos ofrece un men desplegable con todas las bases de datos existentes donde seleccionamos la base de datos con la que vamos a trabajar. El comando SQL equivalente a este proceso es CONNECT, y su sintaxis:
CONNECT DATABASE nombre_base_datos

Con el comando CONNECT s vamos a encontrar diferencias importantes dependiendo del sistema gestor con el que trabajemos. Por ese motivo normalmente se realiza desde el interface grfico. Para borrar una base de datos, tan sencillo como:
DROP DATABASE nombre_base_datos

Crear tablas (CREATE TABLE)


Para crear las tablas utilizamos el comando CREATE TABLE, cuya sintaxis es:
CREATE TABLE nombre_tabla ( columna1 tipo_dato, columna2 tipo_dato, ... ..., columnan tipo_dato, CONSTRAINT cp_nombre_tabla PRIMARY KEY (columna1,...,columnan), [CONSTRAINT cal_nombre_tabla UNIQUE (columna1,...,columanan), [CONSTRAINT caj_nombre_tabla FOREIGN KEY (columna1,...,columnan) REFERENCES tabla] )

Las posibilidades de CREATE TABLE son muchas ms de las que he mencionado en la lista anterior pero realmente no son utilizadas. Por defecto, cuando creamos una tabla todos los campos de la tabla admitirn valores nulos. En principio es lo adecuado. Solamente encontraremos problemas con los campos que sean claves primarias o alternativas, puesto que por definicin estos campos siempre tiene que tener valor, nunca pueden estar vacos. Por ello, en estas columnas estaremos obligados a aadirles la opcin NOT NULL, que obliga a que

esos campos no admitan valores nulos. Esa opcin tambin tendremos que utilizarla en los campos que sean claves ajenas y estemos obligados a que todos los registros de nuestra tabla estn relacionados a travs de esa clave ajena. La forma de utilizacin es muy sencilla:
columna1 tipo_dato NOT NULL,

Ahora vamos a conocer los tipos de datos que podemos aplicar a los campos. SQL nos ofrece gran variedad de tipos de datos, aunque como ocurre siempre, nos acostumbramos a utilizar unos pocos y si en alguna ocasin necesitamos plasmar alguna situacin un poco ms especial recurrimos a la ayuda de SQL para ver ms detalladamente otros tipos de datos o nos creamos los nuestros propios.

Integer Smallint Tinyint Real Datetime Char Varchar Text

enteros comprendidos entre -231 (-2.147.483.648) y 231 - 1 (2.147.483.647). enteros comprendidos entre 215 (-32.768) y 215 - 1 (32.767). enteros comprendidos 0 y 255. flotantes comprendidos entre -3,40E + 38 y 3,40E + 38. fechas. caracteres fijos hasta 8.000. caracteres variables hasta 8.000. caracteres variables hasta 231 - 1 (1.147.483.647).

Un pequeo comentario sobre los tipos de datos. La diferencia entre caracteres fijos (Char) y caracteres variables (Varchar) estriba en que si nosotros hacemos con Char una reserva de memoria de 50 posiciones y al introducir datos solamente utilizamos 20, el resto ser memoria desperdiciada, mientras que si hemos realizado la reserva utilizando Varchar, caracteres variables, si al final solamente utilizamos 20, el resto de memoria ser liberada. Lo ms adecuado es utilizar siempre para caracteres Varchar, utilizando Char solamente en aquellos casos en que sepamos de antemano que siempre se va a consumir todo el espacio reservado, como podran ser campos como los nmeros de telfono, cdigos de texto de tamao fijo, etc. Si en algn momento necesitamos tener un campo entero que sea autonumrico, es decir, que el sistema gestor vaya controlando su valor e incrementndolo o decrementndolo de forma automtica, sin que nosotros tengamos que preocuparnos por ello, tenemos que utilizar la opcin IDENTITY. Esta opcin necesitar dos parmetros, la inicializacin, el valor por el que tiene que comenzar, y el incremento, en el que indicamos el valor de incremento, tanto si es positivo como negativo. Su sintaxis:
columna1 integer identity (1,1),

Segn el ejemplo anterior, el campo columna1, ser un autoincrementable que comenzar en el valor 1 e ir incrementando de uno en uno. Y como no hay mejor forma de aprender que trabajando un poco, vamos a ver como seran los comandos SQL para la creacin de nuestras tablas de ejemplo.
Create table Clientes ( DNI char(9) not null, Nombre varchar(50), Direccion varchar(60), Ciudad varchar(30), CP char(5), Telefonochar(9), constraint cp_Clientes ) primary key (DNI)

Fijmonos en la creacin de tabla que acabamos de realizar, y destaquemos algunos detalles. El DNI es la clave primaria, as queda definido en la ltima lnea de la instruccin de creacin de la tabla, adems, a esta clase, se le ha dado el nombre de cp_Clientes, como ya se haba recomendado en el apartado de Convenciones de diseo. Si la clave primaria de nuestra tabla Clientes es el DNI, por definicin este campo nunca podr contener valores nulos, por lo que vamos a tener que indicrselo, indicacin que hacemos, tal como se aprecia en el listado, aadindole al campo la opcin NOT NULL.
create table ( Numero Fecha Total DNI Facturas integer identity (1,1) not null, datetime, real, char(9),

constraint cp_Facturas primary key (Numero), constraint caj_Facturas foreign key (DNI) references Clientes )

En la creacin de la tabla Facturas nos encontramos con el comando IDENTITY, que indica que el nmero de factura se ir generando automticamente comenzando por el nmero de factura 1 y creciendo de uno en uno. Tambin nos encontramos la definicin de una clave ajena, el campo DNI ser una clave ajena qe relacione una factura con un cliente.
create table Articulos ( Codigo integer not null, Nombre varchar(40), PrecioCompra real, IVA real, constraint cp_Articulos primary key (Codigo) )

create table LineasFactura ( Numero integer identity(1,1) not null, Factura integer not null, Cantidadinteger, Articulointeger not null, Precio real, Total real, constraint cp_LineasFactura primary key (Numero), constraint caj_LineasFactura1 foreing key(Factura) references Facturas, constraint caj_LineasFactura2 foreing key(Articulo) references Articulos )

Aqu nos encontramos con la existencia de dos claves ajenas, como podemos ver sus nombres son el mismo solamente que numerados para que no haya error. Adems a los campos de estas dos claves ajenas se les ha asignado la caracterstica de no poder tomar valores nulos. Por lo tanto, siempre que exista una lnea de factura sta va a tener que pertenecer a una factura y ser de la venta de un artculo, no pueden existir lneas de factura que no cumplan estas condiciones. En realidad el comando CONSTRAINT no es de obligado cumplimiento, podramos definir claves, tanto ajenas como primarias sin la necesidad de utilizar CONSTRAINT pero no podramos darles un nombre a dichas claves. En siguientes apartados veremos que inconveniente se nos plantea si tomamos la determinacin de no dar nombre a nuestras claves.

Inserccin, modificacin y borrado de datos (INSERT,UPDATE, DELETE)


Una vez que ya tenemos creadas las tablas podemos comenzar a trabajar con los datos, insertando, modificando y borrando datos. Que cmo?, pues lo vemos enseguida. A continuacin la sintaxis de cada uno de los procesos respectivamente:
INSERT INTO tabla [(columna1,...,columnan)] VALUES (valor1,...,valorn) UPDATE tabla SET columna1=valor1,...,columnan=valorn WHERE condicion DELETE FROM tabla WHERE condicion

Bueno, esta sintaxis parece ms sencilla que la vista en el apartado anterior. El comando INSERT no tiene ningn secreto, es muy sencilla su forma. Donde podemos encontrar algn problema es con la actualizacin y el borrado, problema en el sentido de entender y a posteriori determinar correctamente la condicin de la clusula WHERE. Las filas de la tabla que cumplan la condicin de la clusula where ser las filas que sufran la actualizacin o el borrado dependiendo del comando utilizado. Vamos a unos ejemplos.
Insert into Clientes (DNI,Nombre,Direccion,Ciudad,CP,Telefono) values (21547789,Agapito Lafuente Corral,c./La plaza nueva,Alicante,03005,987785655) Insert into Clientes (12456445,Maria del mar Sanchez Juan,c./La marina,Madrid,25455,887452114)

En la segunda insercin se me ha olvidado poner los nombres de los campos de la tabla, pero no es incorrecto. Si cuando realizamos una insercin sta afecta a todos los campos de la tabla no es necesario que indiquemos los nombre de los mismos, solamente es necesario cuando vayamos a realizar inserciones en las que algunos campos del nuevo registro no vayamos a rellenarlos, es este caso esos campos en blanco quedarn definidos con el valor NULL. Aqu hay que hacer una pequea llamada de atencin. Podemos perfectamente hacer inserciones que solamente afectan a un subconjunto de los campos de un registro y el resto dejarlo en blanco, pero tenemos que tener la precaucin de nunca dejar en blanco ningn campo que hayamos definido como NOT NULL, nos dara un error y no realizara la insercin.
/* Actualiza la direccin y el CP del cliente con DNI 21547789 */ Update Clientes set Direccion=Plaza Mayor, CP=66789 where DNI=21547789 /*Borra el cliente con DNI 12456445 */ Delete from Clientes where DNI=12456445 /* Borra todos los clientes de los que no tengamos nombre */ Delete from Clientes where Nombre is NULL

Como podemos apreciar en los ejemplo de los borrados y actualizaciones, utilizar estos procedimientos no tiene, al igual que las inserciones, una gran complicacin. El pequeo problema, en los dos primeros, estriba en la clusula WHERE. Los ejemplos mostrados nos ensean como utilizar WHERE en sus posibilidades ms sencillas, obviamente, podramos generar condiciones de borrado y actualizacin algo ms complejas. Dejo para el artculo del prximo nmero de la revista Sntesis el abordar casusticas ms complejas de la clusula, donde conoceremos con detalle toda su potencia. No obstante voy a citar, junto con algn ejemplo ms, algunos de los operadores que podemos utilizar en ella:

AND Es el y lgico. OR Es el o lgico. NOT Es el negador lgico. <, >, <=, >=, =, <> Son los comparadores. BETWEEN Especifica un intervalo de valores. LIKE Compara con un modelo. Ver tabla apartado Creacin de reglas para datos.

IN Compara con una lista de datos.

/* Borra todas las facturas emitidas antes del 1/1/2000 */ Delete from Facturas where fecha < 1/1/2000 /* Actualiza el valor del descuento al 25% a todos los clientes cuya ltima compra est entre 200000 y 300000 pesetas */ Update Cliente set descuento=25 where total_ultima_compra between 200000 and 300000 /* Borra todos los articulos cuyo cdigo comienza por 210 */ Delete from Articulos where codigo like 210%

Modificar y borrar una tabla (ALTER TABLE, DROP TABLE)


Si necesitamos borrar una tabla, situacin que se da en raras ocasiones, el comando es:
DROP TABLE nombre_tabla

Con todo el trabajo que lleva crear una tabla y lo fcil que es borrarla. Hay que llevar cierta precaucin si la tabla se encuentra relacionada con otras tablas. Y ahora, despus del tremendo esfuerzo que nos ha supuesto conocer la sintaxis para el borrado de la tabla, je, je, vamos a continuar con nuestra lnea normal, ALTER TABLE. ALTER TABLE, a nadie se le escapa, sirve para realizar modificaciones de definicin sobre las tablas ya generadas, modificaciones aadiendo o eliminando campos o claves. Su sintaxis:
ALTER TABLE tabla {ADD {COLUMN tipo de campo[(tamao)] [CONSTRAINT indice] CONSTRAINT indice multicampo} | DROP {COLUMN campo CONSTRAINT nombre del indice} }

Ya lo s, un poquito liado verdad?, venga, vamos a ver unos ejemplos:


/* Agrega un campo Comentario a la tabla Clientes */ Alter table Clientes add column Comentario varchar(255) /* Elimina el campo IVA de la tabla Articulos */ Alter table Articulos drop column IVA /* Aade un campo CIF a la tabla Articulos y despus lo convierte en clave ajena para relacionar cada artculo con el proveedor que lo suministra. El CIF es el identificador de un proveedor */ Alter table Articulos add column CIF char(9) Alter table Articulos add constraint caj_Articulos foreing key (CIF) references Proveedores /* Aunque no tenga sentido, borraremos la clave ajena de la tabla LineasFactura a la tabla Factura */ Alter table LineasFactura drop constraint caj_LineasFactura1

En el apartado donde he explicado como se crean las tablas he comentado que cuando generamos una clave, bien sea ajena, primaria o alternativa, el comando CONSTRAINT no es obligatorio incluirlo aunque si recomendable, ahora podemos darnos cuenta del por qu. Si no utilizamos CONSTRAINT no podremos poner un nombre a la nueva clave generada, si la clave no dispone de nombre despus no podremos tratarla con otros comandos como son los vistos en este apartado. No cuesta nada, al generar las claves, otorgarles un nombre, y podemos evitar problemas ms adelante.

Creacin y eliminacin de reglas para los datos (CREATE RULE, SP_BINDRULE, DROP RULE, SP_UNBINDRULE)
Las reglas nos van a permitir tener un control sobre los datos que se insertan en nuestras tablas, son reglas de validacin de datos. A travs de una regla, vamos a definir una serie de condiciones, o podemos ver tambin como asignar un formato a los datos de los campos. Cuando realicemos una insercin en un registro, sta se llevar a termino solamente si los datos cumplen las condiciones, o tienen el formato, que hemos impuesto en la regla. Las reglas que generemos se asociarn a campos de nuestras tablas. No podemos asociar una regla a una tabla completa, solamente a uno de sus campos. El comando para crear reglas es CREATE RULE, y su sintaxis es muy sencilla:
CREATE RULE nombre_regla AS @variable LIKE expresion1 [OR @variable LIKE expresion2 ... OR @variable LIKE expresionN]

Una vez que hemos creado nuestra regla tendremos que hacerle saber al sistema a qu campo de qu tabla tiene que ir asociada, es decir, tenemos que indicar qu datos concretos tiene que controlar. La vinculacin de una regla a un campo concreto de nuestra base de datos se realiza con el comando SP_BINDRULE, y es as de fcil:
EXEC SP_BINDRULE nombre_regla, 'tabla.campo'

El parmetro expresion del comando LIKE define el dominio correcto de los datos, es decir, define la forma o regla que tienen que cumplir los datos para poder ser aceptados y por lo tanto introducidos en el campo. A continuacin vamos a ver de que smbolos disponemos para crear dicha expresin:

% Cualquier cadena de 0 o ms caracteres. _ (subrayado) Cualquier carcter individual. [ ] Carcter individual dentro de un conjunto o intervalo: [abcde], [a-e] [ ^ ] Negacin

Vamos a despejar las nubes de nuestras mentes, cmo?, pues como siempre, con unos ejemplitos. Imaginemos una tabla de asignaturas donde tenemos todas las asignaturas que se imparten en un colegio. En la tabla tendremos un campo dia que indica el da que esa asignatura es impartida. Las asignaturas solamente se imparten de lunes a viernes, situacin que tendremos que controlar a la hora de introducir los datos de las asignaturas en la tabla. Una forma de controlarlo sera perfectamente con una regla.
create rule dias_lectivos as @dia like 'lunes' or @dia like 'martes' or @dia like 'miercoles' or @dia like 'jueves' or @dia like 'viernes' exec sp_bindrule dias_lectivos, 'asignaturas.dia'

Imaginemos una tabla Articulos de una tienda de muebles que slo comercializa muebles de madera, concretamente slo de roble, cerezo y haya.
create rule tipo_madera as @madera like'roble' or @dia like 'cerezo' or @dia like 'haya' exec sp_bindrule tipo_madera, 'articulos.material'

Imaginemos una tabla Articulos de una fbrica de componentes electrnicos donde el cdigo de los nuevos artculos debe tener siempre el mismo formato, comenzar por la letra H, despus una letra y por ltimo tres nmeros.
create rule restriccion_codigo as @codigo like 'H[A-Z]7[0-9][0-9][0-9]' sp_bindrule restriccion_codigo, 'articulos.codigo'

Si necesitamos borrar una regla creada, el comando es DROP RULE, pero antes de borrarla, si ya la habamos vinculado a algn campo, tendremos que desvincular la regla del campo al que est vinculada. El comando para desvincular reglas es SP_UNBINDRULE. Si no desvinculamos antes de borrar la regla, se producir un error y no la podremos borrar. La sintaxis de estos comandos es:
EXEC SP_UNBINDRULE 'tabla.campo' DROP RULE nombre_regla

Una vez desvinculado el campo de su regla podremos vincularle otra regla diferente.

Creacin y eliminacin de tipos (SP_ADDTYPE, SP_DROPTYPE)

definidos

por

el

usuario

Como usuarios podemos crearnos nuestros propios tipos de datos. La principal utilidad de esta posiblidad en estos momentos para nosotros ser ahorrarnos trabajo. Si vamos a tener en nuestra base de datos en varias tablas un campo que va a ser del mismo tipo, al cual vamos a tener que asociarle una regla, es siempre ms cmodo crearnos un tipo de dato para l y asociarle una regla a ese tipo de dato, el cual, cada vez que lo utilizamos para definir un campo cualquiera de nuestras tablas, este campo ya tendr asociada la regla. Si no obramos as, tendramos que definirnos el campo en cada una de las tablas con un tipo de dato simple y luego a cada campo tener que ir asocindole por separado la regla, es una solucin mucho ms laboriosa que la primera. Definiendo un tipo de dato, o definiendo un tipo de dato y vinculndole una regla, ahorramos tiempo y esfuerzo, porque solamente el trabajo lo tendremos que realizar una vez, ya que al asociar a diferentes campos de diferentes tablas el tipo de dato generado, estos campos ya estarn perfectamente definidos, con regla incluida. Sin embargo, si no lo hacemos as, tendremos que repetir el mismo proceso tantas veces como el campo aparezca en nuestra base de datos. Para definir o generar, un tipo de dato por el usuario el comando es ADD_TYPE:
SP_ADDTYPE nombre_tipo_dato_usuario, 'tipo_dato_simple'

Para vincular una regla con un tipo de dato de usuario, el comando tambin es SP_BINDRULE, como hemos visto en el apartado anterior, pero con una pequesima diferencia sintctica, las comillas:
EXEC SP_BINDRULE nombre_regla, tipo_dato_usuario

Para desvincular un tipo de dato de usuario de su regla asociada, el comando, al igual que ocurre con la vinculacin, es el mismo que para desvincular una regla de un campo de una tabla, y tambin sufre la misma variacin que el comando de vinculacin. El comando es SP_UNBINDRULE, y su sintaxis:
EXEC SP_UNBINDRULE tipo_dato_usuario

Veamos un ejemplo. Si en nuestra base de datos vamos a tener un campo telfono varias veces repetido, una vez en la tabla de clientes, otra en la de proveedores, otra en la de colaboradores y otra vez ms en la de subcontratados, y siempre este campo va a tener el mismo formato, nueve nmeros, la mejor opcin sera definirlo como tipo de usuario y asignarle una regla. De forma que cuando en cada una de las tablas generemos el campo telfono, le asignemos este tipo de dato donde ya tenemos incorporado el formato y la regla de validacin. La secuencias de instrucciones sera:

sp_addtype tipo_telefono, 'char(9)' create rule telefono_correcto as @telefono like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' exec sp_bindrule telefono_correcto, tipo_telefono create table clientes ( ... telefono tipo_telefono, ... )

Si queremos borrar el tipo de dato definido por el usuario, SP_DROPTYPE. Pero si tiene una regla vinculada antes tendremos que romper el enlace que les une. Sera conveniente que si la regla no la vamos a asignar a otro tipo de dato o a otro campo de alguna tabla, borrar la regla. Partiendo del ejemplo del nmero de telfono vamos a borrar el tipo de dato. Como est vinculado a una regla, antes tendremos que desvincular y adems, como la regla ya no tiene sentido la borraremos tambin.
Exec sp_unbindrule tipo_telefono drop rule telefono_correcto sp_droptype tipo_telefono

El borrar un tipo de dato de usuario no es una accin que se suela realizar, a no ser que inmediatamente despus de haberlo creado nos demos cuenta que est mal definido, o si el campo o campos de las tablas para los que se defini el tipo de datos los eliminamos de sus tablas correspondientes.

Creacin y borrado de valores por defecto (CREATE DEFAULT, SP_BINDEFAULT, DROP DEFAULT, SP_UNBINDEFAULT)
Un valor por defecto es un valor que se le asigna a un campo de la tabla mientras haya ausencia de otro valor introducido por el usuario. Las instancias del campo tendrn por valor su valor por defecto si ste no se cambia. Cuando un campo, en la mayora de las ocasiones, va a tener siempre un valor concreto, este valor se le puede asignar por defecto, de forma que a no ser que a la hora de la insercin de un nuevo registro o de su actualizacin lo cambiemos, siempre permanecer con l. Los pasos para crear un valor por defecto son: primero crear el valor por defecto, CREATE DEFAULT, y segundo vincular este valor por defecto, o a un campo determinado de una tabla o a un tipo de dato definido por el usuario. Para vincular, el comando es SP_BINDEFAULT, y la sintaxis de los comandos es:
CREATE DEFAULT nombre_valor as valor EXEC SP_BINDEFAULT 'nombre_valor, 'tabla.campo' /* Para campo concretos de tablas */ EXEC SP_BINDEFAULT nombre_valor, tipo_dato_usuario /* Para tipos de datos de usuarios */

Un ejemplo. En una tabla de datos de trabajadores de una empresa donde se reflejan sus datos laborales mensuales, tenemos un campo horas_trabajadas, que refleja las horas trabajadas por casa empleado al mes. A no ser que el empleado falte por algn motivo injustificado al trabajo, sus horas trabajadas mensuales son siempre las mismas, supongamos 120. Podramos aplicarle a este campo un valor por defecto que nos evite para cada trabajador tener que estar siempre introduciendo este valor. Solamente tendremos que cambiar el valor cuando el trabajador no se ajuste a las horas normales de trabajo.
create default horas_trabajadas_120 as 120

exec sp_bindefault 'horas_trabajadas_120', 'trabajo_mes.horas_trabajadas'

Los valores por defecto definidos se puede borrar con el comando DROP_DEFAULT, pero si los tenemos ya vinculados previamente tendremos que romper el enlace con SP_UNBINDEFAULT. La sintaxis?, enseguida:
DROP DEFAULT nombre_valor SP_UNBINDEFAULT 'tabla.campo' /* Para campos concretos de tablas */ SP_UNBINDEFAULT tipo_dato_usuario /* Para tipos de datos definidos por el usuario */

Si deseramos borrar el valor por defecto utilizado en el ejemplo anterior, primero, a nadie se le escapa ya, tendramos que desvincularlo del campo o del tipo de dato de usuario y despus proceder a su eliminacin. Veamos la secuencia de instrucciones:
sp_unbindefault 'trabajo_mes.horas_trabajadas' drop default horas_trabajadas_120

Breve anticipo del siguiente artculo. Las consultas con SQL, de momento...
Bueno, ya hemos llegado casi al final. A lo largo de todo el artculo hemos conocido los fundamentos de SQL, un lenguaje soportado por todos los grandes gestores de bases de datos, que nos permite trabajar con nuestros datos con una independencia del gestor. SQL da a da se instaura ms en el mercado con lo que se hace ya imposible pensar en trabajar con bases de datos sin pensar en SQL. Hasta aqu hemos conocido como podemos definir nuestros datos, en el prximo artculo, dentro de dos meses, veremos como podemos trabajar con ellos. Como se que la espera es larga voy a iniciar un poco los temas que podremos conocer , espero que antes que podamos darnos cuenta, en lo que ser una continuacin de hasta lo aqu expuesto. No sirve de nada que diseemos nuestra base de datos, sus tablas, sus reglas, nuestros propios tipos de datos, introduzcamos datos, etc..., si despus no vamos a manipularlos, a darles vueltas, a jugar con ellos. Uno de los comandos que SQL nos ofrece para divertirnos con nuestros datos es SELECT, de hecho, es uno de los ms conocidos de todo el lenguaje. No vamos a detallar en este momento como utilizar SELECT solamente pondremos su sintaxis ms sencilla y mostrar algunos ejemplos de utilizacin.
SELECT campo1[, campo2, ... ,campoN] FROM tabla1 [, tabla2, ... ,tablaN] [ WHERE condicion1 [AND condicion2 | OR condicion2 | ... | AND condicionN | OR condicionN] ]

Traducido a un lenguaje natural podramos interpretar la sintaxis anterior como: selecciona estos campos que se encuentran en estas tablas si cumplen estas condiciones. Esta sera una forma muy llana de interpretar el comando SELECT, y muy poco ortodoxa, pero sencilla para el que nunca haya visto antes el comando. Vamos a poner un cuantos ejemplos, antes de verlos recomiendo que se recuerde el apartado insercin modificacin y borrado de datos, de este mismo artculo, donde explicamos, a grandes rasgos, el funcionamiento de la WHERE.
/* Tenemos una tabla Artculos y queremos ver todos sus datos */

select * from Articulos /*De la tabla Artculos slo queremos ver los datos de los campos Cdigo y Nombre del artculo */ select Codigo, Nombre from Articulos /* El mismo caso que el anterior pero de los artculos cuyo precio de venta sea mayor que 1000 pesetas */ select Codigo, Nombre, PrecioVenta from Articulos where PrecioVenta > 1000 /* El mismo caso que el anterior pero los artculos que tengan un precio de venta comprendido entre 1000 y 3000 pesetas */ select Codigo, Nombre, PrecioVenta from Articulos where PrecioVenta between 1000 and 3000 /* Todos los clientes que residan en la ciudad de Alicante */ select * from Clientes where Ciudad=Alicante /* Todos los artculos cuya materia prima sea el acero o el aluminio */ select Nombre from Articulos where materia=aluminio or materia=acero

Y as podramos continuar en innumerables ejemplos hasta llegar a determinar toda la potencia de SELECT. Ha llegado ya el momento de despedirnos, espero haber ayudado a que conozca mejor SQL, y a que se interese, si no lo estaba ya, por este mundo de las bases de datos. Le emplazo para los siguientes nmeros de la revista Sntesis donde continuar buceando por este ocano tan grande, el Ocano Bases de datos, para intentar que usted, desde m pequea contribucin, siempre se mantenga a flote en l y sin perder el rumbo. Un saludo, muchas gracias y hasta pronto.

Manipulacin de datos en SQL. Las Consultas.


scar Javier Segura Amors - oscarjsa@hotmail.com

Las consultas de SQL con su archiconocido SELECT, de ahora en adelante, uno de nuestros mejores amigos.
Hola de nuevo. Continua aqu la serie sobre el lenguaje SQL que comenz en el nmero anterior de la revista. Lo primero de todo y antes de proseguir, vamos a hacer un poco de memoria para recordar las bases que ya quedaron sentadas en el artculo anterior y que nos van a servir de punto de partida en ste. En el anterior artculo comenzamos viendo que es SQL (Lenguaje de Consultas Estndar), vimos que era un lenguaje para trabajar con las bases de datos, que era un lenguaje muy difundido por su alta estandarizacin y que prcticamente la totalidad de los sistemas gestores de bases de datos lo trabajaban y en muchas ocasiones, sin diferencias notables en su forma. Vimos que tiene dos mbitos de trabajo, pues podemos clasificar todas sus instrucciones dentro de dos grandes grupos: las instrucciones que trabajan con la estructura de los datos, o lenguaje de definicin de datos (LDD) y las instrucciones que trabajan con los datos en s, o lenguaje de manipulacin de datos (LMD). En el pasa artculo nos centramos solamente en el lenguaje de definicin de datos, momento en el cual abordamos las instrucciones ms importante dentro del grupo de definicin de datos, como las instrucciones para crear las tablas, las reglas, los tipos de datos, insertar valores, borrarlos, modificarlos,..., prometiendo una continuacin al emplazaros a todos para la siguiente entrega donde abordara las instrucciones de manipulacin de datos, y como lo prometido es deuda, aqu estoy de nuevo. En el artculo de este nmero vamos a empezar a conocer las instrucciones de manipulacin de datos. Estas son muchas y variadas por lo que, de momento, no las vamos a tratar en su totalidad. Vamos a empezar por el principio, centrndonos en las consultas bajo SQL dejando ya para el prximo artculo las vistas y los procedimientos almacenados. Sera un disparate, por su complejidad y extensin, pretender conocer todo el lenguaje de manipulacin de datos en solamente un artculo. De esta forma, vamos a poder centrarnos en algo ms concreto, las consultas, verlas con profundidad y descubrir toda la potencia que nos ofrecen. Bueno, si nos vamos a centrar en las consultas, lo primero que nos tendremos que plantear es, qu es una consulta?, para qu sirve?. Preguntas totalmente fuera de lugar puesto que todos ya sabemos a estas altura que las consultas son unos procedimientos que nos van a permitir interrogar a nuestra base de datos lanzando preguntas a las tablas para obtener de esta forma los datos que nosotros necesitamos en un momento determinado. De nada sirve introducir datos en unas distribuciones de tablas si despus no podemos recuperarlos, es ms, ya no basta recuperar esos datos, sino que adems queremos recuperar no la totalidad de los datos, solamente vamos a querer recuperar en cada momento los datos que no son necesarios. Para eso existen los criterios de bsqueda de datos dentro de las consultas. La complejidad de las consultas estriba, no en hacer la consulta en si, puesto que una consulta que nos muestre todos los datos de una tabla o de un conjunto de ellas no tiene ningn misterio. Muchas veces la complejidad la vamos a encontrar en generar esos criterios, esas condiciones que van a tener que satisfacer los datos que la consulta nos va a mostrar, los datos que nosotros queremos conocer de entre todos los que tenemos almacenados. Y ya sin ms dilacin empecemos que tenemos mucho camino por recorrer, suerte en el recorrido.

Base de datos de ejemplo. Gestin de proveedores.


Junto con el artculo encontrareis varios ficheros para descargar. Estos ficheros son un apoyo, un complemento para poder entender mejor los diferentes apartados que a continuacin abordaremos. Durante todo el artculo completar las explicaciones de cada apartado con ejemplos. Estos ejemplos estn realizados sobre una base de datos, Gestin de proveedores, la cual podra ser un pequeo ejemplo de control de artculos de una empresa informtica. En los ficheros encontrareis el scrip de SQL para generar la base de datos e introducir en ella unos datos, que por supuesto son imaginarios, datos suficientes para poder trabajar cmodamente. Adems encontrareis otros ficheros con propuestas de ejercicios y sus soluciones, basados tambin en la en Gestin de proveedores, que servirn para poder practicar todos los apartados vistos en el artculo. Los ficheros son 3, los cuales os describo a continuacin:
?

Fichero BaseDatos.sql: Dentro de este fichero encontrareis el scrip de SQL para la creacin de la base de datos de Gestin de proveedores junto con las instrucciones de insercin de los datos para que se pueda trabajar ya con ella. El scrip est optimizado para utilizarlo en SQL Server 7, lo cual no quiere decir que no vaya a funcionar en otros gestores. Si lo queremos utilizar en Interbase tendramos que hacer dos pequeas modificaciones: en la creacin de las tablas sustituir el tipo de datos para fechas, datetime, por el tipo soportado por Interbase, date, y en las inserciones de los datos, las fechas que estn escritas en el formato dd/mm/aaaa cambiarlas por el formato mm/dd/aaaa. Tras estas dos modificaciones podramos correr el scrip en Interbase sin ningn problema. Fichero Ejercicios.txt: Donde encontrareis los enunciados de propuestas de ejercicios para poder practicar todo lo aprendido. Los ejercicios estn basados en la base de datos de Gestin de proveedores. Fichero Soluciones.sql: Donde encontrareis las soluciones a los ejercicios propuestos en el fichero Ejercicios.txt en forma de scrip de SQL.

Os presento ahora las tablas de la base de datos de ejemplo Gestin de proveedores:


VENDEDOR ( numvend SMALLINT not null, nomvend VARCHAR(30), nombrecomer VARCHAR(30), telefono VARCHAR(15),calle VARCHAR(30), ciudad VARCHAR(20), provincia VARCHAR(20), cod_postal CHAR(5) ) Clave primaria: (numvend)

PIEZA ( numpieza VARCHAR(16) not null, nompieza VARCHAR(30), preciovent INTEGER ) Clave primaria: (numpieza)

PRECIOSUM ( numpieza VARCHAR(16) not null, numvend SMALLINT not null, preciounit INTEGER, diassum SMALLINT, descuento SMALLINT ) Clave primaria: (numpieza,numvend) Clave ajena: (numpieza)--> PIEZA Clave ajena: (numvend)--> VENDEDOR

PEDIDO ( numpedido SMALLINT not null, numvend SMALLINT, fecha datetime ) Clave primaria: (numpedido) Clave ajena: (numvend)--> VENDEDOR

LINPED ( numpedido SMALLINT not null, numlinea SMALLINT not null, numpieza VARCHAR(16), preciocompra INTEGER, cantpedida SMALLINT, fecharecep datetime, cantrecibida SMALLINT ) Clave primaria: (numpedido,numlinea) Clave ajena: (numpedido)--> PEDIDO Clave ajena: (numpieza)--> PIEZA

INVENTARIO ( numbin SMALLINT not null, numpieza VARCHAR(16) not null, cantdisponible SMALLINT, fecharecuento datetime, periodorecuen SMALLINT, cantajuste SMALLINT, cantreord SMALLINT, puntoreord SMALLINT ) Clave primaria: (numbin) Clave alternativa: (numpieza) Clave ajena: (numpieza)--> PIEZA

Es una ventaja, si antes de realizar los ejercicios y tras crear la base de datos e insertar los datos, listamos los datos de cada una de las tablas por impresora. De esta forma al tener un listado de cada una de ellas podemos comprobar sobre el papel si los datos obtenidos con la ejecucin de nuestras consultas son los datos correctos o la consulta es incompleta o errnea. Qu como podemos hacer eso?, muy fcil, veamos el siguiente apartado. No perder de vista el esquema de las tablas que se han presentado, puesto que entenderemos mejor las explicaciones de los apartados.

Seleccin de columnas en consultas de una sola tabla (SELECT, FROM)


En las consultas, la seleccin de las columnas que vamos a mostrar se realiza con las clusulas SELECT, para indicar las columnas a mostrar y FROM para indicar la tabla en la que se encuentran dichas columnas. Su sintaxis:
SELECT [DISTINCT] Columna1,...,ColumnaN FROM Tabla

La sintaxis descrita, la cual es muy simple, servira solamente para mostrar las columnas de una nica tabla, puesto que en la clusula FROM solamente hemos especificado una tabla. En siguientes apartados veremos como realizar consultas en las que se utilizan varias tablas, no basta con indicar las diferentes tablas en la clusula FROM. Si queremos mostrar la totalidad de las columnas de una tabla no es necesario enumerarlas todas dentro de la clusula SELECT, bastara con porner un *, indicativo de totalidad. En el apartado anterior recomendaba que se listaran todos los datos de cada una de las tablas. Si queremos mostrar toda la tabla Vendedor, podramos comenzar por ella misma, es decir, todos sus datos, todas sus columnas:
select *

from vendedor

Al poner un * nos ahorramos el tener que escribir el nombre de todos sus campos. Esta consulta la tendramos que repetir para cada una de las seis tablas. Si ahora quisiramos ver solamente los datos correspondientes al numero de vendedor y su nombre, sin querer mostrar la informacin del resto de las columnas, tendremos que seleccionar exclusivamente estos campos. Recordar que aunque la tabla seleccionada tenga ms campos, solamente se mostrarn aquellos que indiquemos, seleccionemos en la clusula SELECT:
select numvend, nomvend from vendedor

Si lo deseamos, podemos dar un nombre a las columnas que mostramos en la consulta. Para renombralas bastar con escribir el nombre que les queramos dar, entre comillas si es un nombre compuesto o si es un nombre simple directamente, despus del nombre real de la columna en la sentencia SELECT. Si no lo hacemos el gestor nos mostrar el nombre real de las columnas. Interbase no soporta los renombramientos compuestos de columnas.
select numvend Nmero de vendedor, nomvend Nombre del vendedor from vendedor

Cuando renombramos las columnas, indicar, que el nuevo nombre pertenece solamente al mbito de la consulta, por lo que nunca se cambiar el nombre real de la columna dentro la de base de datos, es lo lgico. Sera un autntico galimatas si cada vez que renombramos una columna en una consulta ese nuevo nombre tambin se extendiera a las correspondientes tablas. El parmetro DISTINCT se utiliza cuando en los datos obtenidos en la consulta tenemos algunas filas que son iguales, con este parmetro eliminaremos de la consulta aquellas filas que sean repetidas.
select distinct provincia from vendedor

Como existen varios vendedores que pertenecen a las mismas provincias, al ejecutar esta consulta obtendramos la provincia de cada uno de los vendedores por lo que tendramos muchos nombres de provincias que se repiten. Para evitarlo indicamos a la consulta que solamente nos muestre aquellas filas que sean diferentes, eliminando as del resultado las que repiten.

Ordenar resultados de la consulta (ORDER BY)


Podemos realizar ordenaciones de los resultados que las consultas nos van a devolver. Podemos elegir que los resultados obtenidos se muestren de forma ascendente o descendente, basndose en los valores de unas determinadas columnas de la consulta. Esto lo conseguimos con la instruccin ORDER BY.
ORDER BY Columna1,...,ColumnaN [ASC|DESC]

ORDER BY lo situaremos siempre por debajo de la clusula FROM, esto no quiere decir que deba ir exactamente bajo esta clusula, puesto que en los siguientes apartados veremos otras instrucciones que podemos utilizar, la nica condicin es que ORDER BY nunca se situe antes que SELECT o FROM. La columnas indican los campos que nos van a servir como criterios de ordenacin, de forma que si indicamos varias columnas siempre se ordenarn los valores en funcin de la primera, y si en la primera se encuentran valores iguales, entonces las filas correspondientes a estos valores se ordenarn segn la segunda columna indicada, y as sucesivamente. ASC y DESC que son dos parmetros opcionales, se utilizan para indicar la ordenacin, si deseamos una ordenacin ascendente o descendente respectivamente. En el caso que se se indique ninguno de los dos parmetros se realizar una ordenacin ascendente.

Si no especificamos nosotros en la consulta ningn orden de listado, los datos sern mostrados en el orden en el que se encuentran en las tablas. Un ejemplo. Mostrar de todos los vendedores su nombre, direccin y nmero de vendedor de forma ordenada.
select nomvend nombre, direccion, numvend nmero vendedor from vendedor order by nomvend

Condicin de seleccin (WHERE)


En la mayora de nuestras consultas no querremos hacer listados de la totalidad de los datos de una tabla, sino que querremos hacer listado parciales segn algn criterio de seleccin de datos, es decir, mostrar solamente aquellos datos que cumplan unas determinadas condiciones, unos determinados criterios. Para imponer estos criterios de seleccin se utiliza la clusula WHERE y su sintaxis es:
WHERE Condicin [and Condicin2 | or Condicin2 | ... | and CondicinN | or CondicinN]

En una clusula WHERE podemos poner tantos criterios de seleccin como necesitemos, uniendo dichos criterios por los los operadores lgicos AND y OR. Los criterios o condiciones se pueden especificar de muchas formas, de momento vamos a ver solamente la forma ms simple, los comparadores : <, >, <=, <=, =, <>, !=, !<, !>. En siguientes apartados utilizaremos clusulas que nos van a permitir simplificar las condiciones o darles mayor potencia. Y como no hay nada mejor que un ejemplo... Antes hemos listado todo el contenido de la tabla vendedor, ahora solamente vamos a querer listar a aquellos vendedores cuya ciudad sea Alicante:
select * from vendedor where ciudad=Alicante

Como la ciudad es un campo de tipo carcter siempre que queramos trabajar con l tenemos que hacerlo poniendo el dato entre comillas dobles. Queremos los vendedores de que pertenezcan a la empresa OLE ESPAA y sean de la ciudad de Madrid:
select * from vendedor where nombrecomer=ole espaa and ciudad=madrid

Y ahora queremos los nmero de pieza y la fecha de recuento de todas aquellas piezas de las que tengamos una cantidad disponible superior o igual a 10 unidades:
select numpieza,fecharecuento from inventario whhere cantdisponible>=10

Llegados a este punto un comentario sobre diferencias de funcionamiento de un gestor de bases de datos a otro. Los ejemplos ahora citados funcionan perfectamente en SQL Server, mientras que si los intentamos utilizar bajo Interbase hay que tener una pequea precaucin, puesto que ste hace distincin entre maysculas y minsculas en los datos, as que tendremos que tener la precaucin de trabajar siempre en nuestra base de datos en un solo formato, o bien maysculas o minsculas. Si el primer ejemplo de todos lo ejecutamos bajo Interbase la consulta no nos hubiera devuelto ningn dato, siendo esto incorrecto, al s haber datos que cumplen el criterio, pero no se muestran porque nosotros no hemos puesto el trmino de condicin en maysculas, tal y como se encuentra el dato almacenado en la tabla.

Consultas con varias tablas


Cuando realizamos consultas en las que vamos a utilizar varias tablas, dos, tres, cuatro, ..., normalmente esas tablas son tablas relacionadas, es decir, unas tablas hacen referencias a las otras a travs de las claves ajenas que hayamos definido en la creacin de las mismas. En pocas ocasiones vamos, en una misma consulta, a visualizar datos de varias tablas que no estn relacionadas. La forma de realizar una consulta utilizando varias tablas es muy sencilla, basta con poner los nombre de las tablas, separadas por comas, en la clusula FROM.
FROM Tabla1,...,TablaN

Poner los nombre de las tablas a utilizar dentro de la clusula FROM sera suficiente si las tablas fueran tablas no relacionadas, es decir, si fuera una de esas consultas que en raras ocasiones se nos va a presentar realizar. Si las tablas estn relacionadas, deberemos dentro de la clusula WHERE indicarlo. La forma de indicarlo es igualando los campos que tienen en comn cada tabla con las dems.
FROM Tabla1, Tabla2 WHERE Tabla1.CampoComun=Tabla2.CampoComun

Vemoslo con un ejemplo. Queremos obtener todas los nmeros de pieza y en que nmero de pedido se han solicitado siendo el nmero de vendedor el 1. Qu nadie se asuste!, parece ms de lo que en realidad es. La solucin?, s, claro, al instante:
select linped.numpedido "Numero pedido",numpieza "Numero de pieza" from linped,pedido where numvend=1 and linped.numpedido=pedido.numpedido

Necesitamos la tabla Pedido puesto que en ella se encuentra el nmero de vendedor al que se realiza el pedido y necesitamos tambin la tabla Linped (Linea de pedido) puesto que en ella se encuentran las piezas que se piden en cada pedido. Estas dos tablas estn relacionadas por el dato Numpedido (Nmero de pedido), que si repasamos el esquema de las tablas, es la clave ajena que existe de Linped a Pedido, y este enlace se lo indicamos a la consulta en el apartado del WHERE, adems tambin dentro de ste apartado indicamos el criterio de que el vendedor tiene que ser el nmero 1. Incluso para que queden ms claros los datos mostrados, renombramos las columnas. En el ejemplo anterior apreciamos como el dato comn en las dos tablas y que sirve de enlace entre ellas es Numperido, y cada vez que hacemos referencia a l tenemos que indicar a que Numpedido nos estamos refiriendo, si al de la tabla Linped o al de la tabla Pedido. Esto lo realizamos escribiendo el nombre de la tabla, un punto y el nombre del campo duplicado, por as llamarlo. Por ese motivo en la clusula SELECT, cuando utilizamos Numpedido le tenemos que anteponer la tabla a la que pertenece. En el caso del SELECT, la tabla a la que pertenece Numpedido es indiferente, puesto que ya en el WHERE nos hemos ocupado de igualar esos nmeros de pedido. Sin embargo no ocurre as en el WHERE, donde si tenemos que hacer corresponder cada nmero de pedido de la igualdad con su tabla, por un lado el Numpedido de la tabla Linped y por el otro el Numpedido de la tabla Pedido. Si no realizamos el enlace entre las tablas dentro de la consulta se producira un producto cartesiano entre los datos de ambas tablas, relacionando as cada dato de la primera tabla con todos los datos de la segunda y por lo tanto mostrndonos un conjunto de datos que no son reales. Recomiendo que pruebes a repetir la consulta anterior suprimiendo el enlace de las tablas y observes el resultado. Es recomendable, para optimizar la consulta, indicar siempre el enlace de las tablas como ltima condicin en el WHERE. Cuando nosotros dentro del apartado FROM indicamos que queremos trabajar con varias tablas, el gestor crea una tabla virtual, dentro del mbito de la consulta, en la que introduce el resultado de realizar el producto cartesiano entre las tablas que nosotros le hemos indicado. Despus sobre esta tabla virtual elimina las filas, los registros, que no cumplan los criterios indicados en el WHERE. Va evaluando sobre los datos de la tabla virtual los criterios por el orden en el que se encuentran escritos, de esta forma si nosotros antes de especificar el enlace hemos especifica el resto de criterios, a la hora de comprobarlos

tendr que operar con menos datos puesto que muchos de ellos ya los habr eliminado porque no cumplan las condiciones anteriores. Entendamos que al comprobar el enlace tiene que recorrer todos los registros de la tabla comprobando la igualdad de cada registro con todos los dems, trabajo muy arduo, ayudmosle a que las comprobacin sea lo ms pequea posible. Tras comprobar todos los datos con los criterios impuestos y los enlaces, los datos que hayan superado todas las condiciones sern los que queden en la tabla virtual, y est nos ser presentada a nosotros como resultado de la consulta.

Rangos de valores (BETWEEN)


En las consultas, la bsqueda de valores entre unos rangos determinados resulta de gran importancia. Podramos hacerlas utilizando los operadores de comparacin, pero existe una forma mejor, la instruccin BETWEEN.
WHERE Columna [NOT] BETWEEN Expresin1 AND Expresin2

La Columna ser la columna dentro de la cual queramos comprobar si existe el valor comprendido dentro del rango que nosotros marcamos. La Expresin1 y Expresin2 ser el menor valor del rango y el mayor valor del rango respectivamente. Los rangos de valores deben de ser numricos o fechas. Fijmonos que podemos realizar selecciones inversas al poder utilizar el operador NOT.

Si queremos encontrar todas aquellas piezas cuyo precio de venta est comprendido entre 500 ptas y 2000 ptas. Tenemos dos formas de hacerlo, la primera, que es la ms larga y la segunda que es la ms adecuada:
/*Primera forma. Para principiantes. No es su caso*/ select * from pieza where preciovent>=500 and preciovent<=2000 /*Segunda forma.*/ select * from pieza where preciovent between 500 and 2000

Si por el contrario, quisiramos encontrar todas aquellas piezas cuyo precio de venta no est comprendido entre 500 y 2000 ptas tambin tenemos dos formas de hacerlo:

/*La primera, que como antes no es la ms correcta*/ select * from pieza where preciovent<=500 or preciovent>=2000 /*La segunda, la buena*/ select * from pieza where preciovent not between 500 and 2000

Bsqueda en listas de valores (IN)


Una lista es una sucesin de valores separados entre comas. La clusula IN nos permite trabajar con una lista de valores, para ello, la sintaxis sera la siguiente:
WHERE Columna [NOT] IN (lista de valores)

De esta forma podemos comparar los datos de una columna de una tabla con una lista de valores de una forma muy sencilla, evitndonos el tener que comparar la columna con cada uno de los valores de forma independiente y uniendo todas esas comparaciones con el operador OR. La lista de valores puede ser de tres tipos: o una lista de valores numricos, en cuyo caso irn separados por comas, o una lista de valores alfanumricos, o fechas, en cuyos casos, cadenas alfanumricas o fechas, irn separados por comas y adems cada uno de ellos encerrado entre comillas dobles o simples. Listar todos las lneas de los pedidos 1,2 y 5.
select * from linped where numpedido in (1,2,5)

Listar los nombres, nmeros y cantidad disponible de todas aquellas piezas suministradas por vendedores de las provincias de Alicante, Madrid o Valencia.
select nompieza "Nombre pieza",li.numpieza "Nmero pieza", cantdisponible "Cantidad disponible", provincia "Provincia" from vendedor ve, pieza pie, inventario inv, pedido pe,linped li where provincia in ("Alicante","Madrid","Valencia") and ve.numvend=pe.numvend and pe.numpedido=li.numpedido and li.numpieza=pie.numpieza and pie.numpieza=inv.numpieza

Comentemos el ejemplo anterior que tiene mucha miga. Lo ms complicado es la cantidad de enlaces que hemos tenido que hacer entre las diferentes tablas. Esta gran cantidad de enlaces es debido a que dos de los datos que queremos obtener estn en una tabla, el tercero est en otra y la condicin que se debe de cumplir est en otra diferente, por eso tanta tabla y tanto enlace. Si nos fijamos en la clusula FROM, tras cada una de las tablas que queremos cargar hemos definido un alias, de forma que cuando queramos, en otro apartado de la consulta, hacer referencia a esa tabla lo podamos hacer de forma ms cmoda utilizando el alias, es simplemente por comodidad. En la clusula WHERE hemos puesto el criterio de la provincia lo primero de todo y despus los enlaces, de esta forma optimizamos la ejecucin de la consulta como ya he explicado en apartados anteriores. En la clusula SELECT hacemos referencia al campo Numpieza, campo o columna que aparece en varias de las tablas que hemos cargado para la consulta, por lo tanto, tendremos que indicar de cuales de dichas tablas queremos que sean obtenidos los datos de dicha columna, como ya previamente habamos enlazado las tablas es indiferente el mbito que le asignemos. Y centrndonos ya en la parte de la consulta que se refiere a este apartado fijaros como indicado en la lista los valores que queremos encontrar, los nombre de las provincias, y como los valores son alfanumrico los hemos escrito entre comillas dobles.

Bsqueda de valores en una cadena (LIKE)


Podemos preguntar por subcadenas dentro de columnas tipo carcter. Para ello usaremos el operador LIKE y su sintxis:
WHERE Columna [NOT] LIKE Expresin

La Expresin puede estar compuesta por los siguientes signos:


?

Letra y nmeros.

? ? ? ?

%: Cualquier cadena de 0 o ms caractres. _: Cualquier carcter individual o ausencia de ste. []: Conjunto de caracteres, como [abcdef], o un intervalo de estos, como [a-e] [^]: Negacin.

Por lo tanto, con los signos citados podemos generar expresiones que representen las posibilidades de cadenas que nosotros buscamos. La clusula LIKE no se utiliza cuando buscamos una cadena en concreto, o un conjunto de cadenas determinadas que no sean parecidas, para eso utilizamos una lista de valores con la sentencia IN. LIKE la utilizaremos cuando busquemos un conjunto de cadenas en las que exista un patrn, donde podamos encontrar una expresin, utilizando los signos permitidos, que nos permita identificar a todas las cadenas del conjunto que buscamos. Dependiendo de lo fcil o complicado que sea encontrar el patrn de las cadenas que buscamos, optaremos por utilizar LIKE, si es fcil encontrar el patrn, o IN, enumerando la totalidad de las cadenas, si no existe patrn o es muy complicado encontrarlo. Es muy importante destacar que se diferencia entre maysculas y minsculas. Encontrar todos los vendedores cuyo nombre es Manuel.
select * from vendedor where nomvend like Manuel %

Nos vemos obligados a utilizar LIKE puesto que sabemos que el nombre debe de empezar por Manuel pero desconocemos cuales van a ser sus apellidos por lo que tendremos que poner el comodn de las cadenas %. Ahora encontrar todos los vendedores cuyo nombre es Manuel o Manolo
select * from vendedor where nomvend like Man[uel,olo] %

Hemos encontrado el patrn, ambos nombre comienzan por las letras Man y depus el sufijo uel o olo, y como en el caso anterior, posteriormente % puesto que desconocemos sus apellidos. Encontrar todos los vendedores que uno de sus apellidos sea Prez.
select * from vendedor where nomvend like % Prez %

Como uno de sus apellidos es Prez, pero desconocemos su nombre y su segundo apellido, en el caso que Prez fuera el primero, o si es el segundo apellido, desconocemos tanto su nombre como su primer apellido, ponemos % tanto delante como detrs. En el caso en el que buscramos solamente a los vendedores cuyo segundo apellido es Prez, deberamos de colocar un solo % delante del apellido, puesto que al estar seguros que Prez es su segundo apellido no habr ningn texto detrs de ste. Encontrar todas las piezas cuyo nmero no empieza por T, tengan a continuacin un guin,tres ceros, cualquier nmero y terminen con cualquier letra.
select * from pieza where numpieza like [^T]-000[0-9]%[A-Z]

Esta ha sido ya, lo reconozco, una bsqueda caprichosa, pero no est de ms hacerla y comprobar la potencia que LIKE nos facilita. Mucha atencin a los signos utilizados y el orden de aparicin.

En Interbase las expresiones compuestas por los signos [ ] o [^] no son soportadas.

Valores nulos (IS NULL)


Cuando se habla de valores nulos, automticamente se piensa en un carcter en blanco, sin embargo, al hacer esta reflexin caemos en un grave error. Un valor nulo es la ausencia de valor, es decir, cuando a una columna no se le atribuye ningn valor. Como casi todos los lenguajes existentes en la actualidad, en SQL tambin existe una palabra reservada que hace referencia al valor nulo, la palabra clave NULL. Para realizar una consulta sobre los valores nulos de una columna especfica basta con seguir la siguiente sintaxis:
WHERE Columna IS NULL

Un ejemplo rapidsimo. Obtener todas las piezas que no tengan descuento aplicado.
select * from pieza where descuento is null

No hay que incurrir en el error tpico de hacerlo as: descuento=NULL o descuento=NULL puesto que de ninguna de las dos formas obtendremos los resultados esperados.

Funciones de agregado
Las funciones de agregado realizan un clculo sobre un conjunto de valores y devuelven un solo valor. Con excepcin de COUNT, las funciones de agregado omiten los valores nulos. A continuacin un listado de las funciones de agregado:
? AVG ([DISTINCT] Expresin): Devuelve la media de los valores de un

grupo. Los valores nulos se omiten.


? COUNT (*|[ALL|DISTINCT] Expresin): Devuelve el nmero de elementos de

un grupo.
? MAX ([ALL|DISTINCT] Expresin): Devuelve el valor mximo de la

expresin.
? MIN ([ALL|DISTINCT] Expresin): Devuelve el valor mnimo de la

? ? ? ?

expresin. Devuelve la suma de todos los valores o de slo los valores DISTINCT en la expresin especificada. SUM ([ALL|DISTINCT] Expresin): Devuelve la suma de todos los valores o de slo los valores DISTINCT en la expresin especificada. Slo puede utilizarse con columnas numricas. Los valores nulos se omiten. STDEV (Expresin): Devuelve la desviacin tpica estadstica de todos los valores de la expresin especificada. STDEVP (Expresin): Devuelve la desviacin tpica estadstica de la poblacin para todos los valores de la expresin especificada. VAR (Expresin): Devuelve la varianza estadstica de todos los valores en una expresin dada. VARP (Expresin): Devuelve la varianza estadstica del llenado para todos los valores en la expresin dada.

Dichas funciones agregadas retornan valores calculados sobre una determinada columna. Estas funciones devuelven un nico valor para todas las tuplas seleccionadas mediante la condicin de la clusula WHERE, si no se especifica sta, el clculo se realiza sobre la totalidad de la columna. Las funciones estadsticas precisan que la expresin que se evale se construya sobre columnas de tipo de datos numricos.

Las expresiones pueden contener el nombre de una columna o un clculo sobre una o varias columnas, Si se especifica la clave DISTINC, la expresin obligatoriamente ha de ser un nombre de columna, y se asume que la funcin se calcula nicamente sobre valores distintos de la expresin. Deberemos tener en cuenta que no se pueden anidar funciones, es decir AVG(MIN(preciovent)) no est permitido. Las funciones de agregado slo se pueden utilizar como expresiones en: la lista de seleccin de una instruccin SELECT, clusula COMPUTE o COMPUTE BY y en la clusula HAVING, la cual veremos a continuacin. Tambin podemos utilizar los operadores aritmticos: + (sumar), - (restar), * (multiplicar), / (dividir) y % (mdulo) para realizar clculos. Unos ejemplos. Obtener la diferencia entre cantidad pedida y cantidad recibida de las lneas del pedido1.
select (cantpedida-cantrecibida) from linped where numlinea=1

Obtener la cantidad de provincias distintas de las que tenemos conocimiento de algn proveedor.
select count(distinc provincia) from vendedor

Las funciones agregadas las vamos a utilizar en la mayora de las ocasiones junto con agrupaciones de los datos.

Agrupaciones y selecciones (GROUP BY, HAVING)


Podemos realizar consultas en las cuales se realicen agrupaciones de filas de las tablas que utilizamos. La agrupacin consiste en formar subconjuntos dentro de una tabla en funcin de los valores que tengan los datos de las columnas por las que deseemos agrupar. Las agrupaciones se realizan con la clusula GROUP BY, la cual siempre tiene que ir situada inmediatamente detrs de WHERE, o en el caso que no existiera inmediatamente detrs de FROM. Su sintaxis es:
GROUP BY Columna1,...,ColumnaN

Cuando realizamos una agrupacin, podramos decir que se forman subconjuntos dentro de la tablaen la que se encuentra la columna por la que agrupamos, de forma que todas las filas que tengan el mismo valor dentro de la columna por la que agrupamos formarn parte del mismo subconjunto. As nos encontraremos como resultado tantos subconjuntos como valores diferentes tienen los datos de la columna por la que hemos agrupado. En el caso que agrupemos por varias columnas simultneamente la explicacin anterior se ampla para varias columnas. Un dato muy importante es que cuando utilizamos GROUP BY las columnas que aparecen en la clusula SELECT pueden ser solamente de dos tipos: columnas agrupadas que aparecen en GROUP BY, o columnas funciones agregadas aplicadas a cualquier otra expresin o columna. Veamos un ejemplo. Imaginemos la tabla Linped (lnea de pedido), en la cual encontramos un listado con todas las lneas de todos los pedidos que se han realizado. En cada lnea encontramos los datos de la pieza que se ha pedido, que cantidad de pieza que se ha pedido, el nmero de pedido al que pertenece esa lnea, etc. Linped no es ms que la tabla detalle de su tabla maestra que es Pedido. Si en Linped tuviramos los siguientes datos, imaginemos, slo por el momento, que Linped tiene esta estructura y estos datos:

Nmero pedido (numpedido) 1 1

Linea pedido (numlinea) 1 2

Nmero pieza (numpieza) AAA BBB

Cantidad pedida (cantpedida) 20 10

Nmero pedido (numpedido) 1 2 2 3 3 3

Linea pedido (numlinea) 3 1 2 1 2 3

Nmero pieza (numpieza) CCC AAA HHH BBB PPP AAA

Cantidad pedida (cantpedida) 15 8 10 22 10 3

Si realizamos un agrupamiento por el nmero del pedido nos encontraramos con tres subgrupos: el primero formado por las filas de las tres lneas de pedido del pedido uno, el segundo subgrupo formado por las dos filas de las lneas del segundo pedido, y el tercer y ltimo subgrupo formado por las tres filas de las lneas de pedido que pertenecen al pedido nmero tres. Si por ejemplo quisiramos saber el nmero de lneas que forman cada uno de los pedidos, claramente necesitaremos utilizar COUNT (numlinea), pero si lo utilizamos sin ms, es decir, sin realizar ninguna agrupacin, lo que obtendremos ser el nmero de lneas de pedido que hay en la tabla, es decir, su nmero de filas. Necesitamos, sin embargo, que el COUNT haga referencia a las lneas de pedido de cada pedido. Se hace necesario que realicemos una agrupacin por el nmero de pedido y as COUNT nos devolver el nmero de lneas de pedido de cada uno de los subconjuntos formados:
select numpedido, count(numlinea) from linped group by numpedido

Ya hemos logrado obtener el nmero de lneas de pedido que forman cada uno de los pedidos. Hemos necesitado agrupar por el nmero de pedido, por lo tanto, como lo tenemos en el GROUP BY estamos obligados a ponerlo tambin en el SELECT. Si intentamos mostrar cualquier otra columna de la tabla Linped veremos que se genera un error, puesto que estamos mostrar una columna por la que no estamos agrupando, recordar este detalle puesto que en muchas ocasiones incurrimos en este error. Otro ejemplo. Queremos obtener para cada una de las piezas que hemos pedido en los primeros 100 pedidos la cantidad total de unidades que han pedido de cada una de ellas.
select numpieza "Nmero de la pieza",sum(cantpedida) "Cantidad pedida" from linped where numpedido<=100 group by numpieza order by numpieza

En esta ocasin no hemos tenido que agrupar por el nmero de pedido, es un dato que nos nos importa ahora, sino que hemos tenido que agrupar por el nmero de la pieza. Y para obtener la cantidad que se ha pedido de cada una de ellas realizamos la suma de todas las cantidades pedidas por cada una de las piezas. Hemos tenido la precaucin de renombrar las columnas y ordenar ascendentemente por el nmero de la pieza para que quede ms claro el resultado de la consulta. Como ya sabemos, disponemos de la clusula WHERE para imponer condiciones sobre las filas que vamos a mostrar en la consulta, de forma que solamente aquellas filas que cumplan las condiciones marcadas en el WHERE sern mostradas. Los grupos tambin tienen su propia clusula para imponer condiciones, la clusula HAVING. Con HAVING vamos a indicar las condiciones que tienen que cumplir los grupos formados por GROUP BY para que puedan ser mostrados en el resultado de la consulta. HAVING simpre estar situado inmediatamente detrs de GROUP BY. Su sintaxis es:
HAVING Condicin1,...,CondicinN

Retomamos los ejemplos anteriores, pero ahora queremos saber el nmero de lneas que forman cada uno de los pedidos, pero solo de aquellos pedidos en los que se hayan pedido ms de cinco unidades entre todas sus piezas.
select numpedido, count(numlinea) from linped group by numpedido having min(cantpedida)>5

Y como remate final, vamos a obtener para cada una de las piezas que hemos pedido en los primeros 100 pedidos la cantidad total de unidades que han pedido de cada una de ellas siempre y cuando esa pieza la hayamos pedido ms de una vez.
select numpieza "Nmero de la pieza",sum(cantpedida) "Cantidad pedida", count(*) from linped where numpedido<=100 group by numpieza having count(*)>1 order by numpieza

Es la misma consulta que ya habamos realizado anteriormente slo que ahora imponemos una condicin al subconjunto, y es que exista ms de una fila. Si existe ms de una fila significa que esa pieza se ha pedido ms de una vez, puesto que estamos agrupando por la pieza, por su nmero, los subgrupos tendrn tantas filas como veces aparezca esa pieza en la tabla de lneas de pedido, o lo que es lo mismo, el subconjunto tendr tantas filas como veces se haya pedido la pieza.

Y en el prximo articulo qu?.


Esto toca ya su fin. Ya hemos andado el camino, por esta vez. Hemos vistos muchas cosas. Hemos hecho un recorrido amplio por las consultas en SQL, nos han presentado al famoso por excelencia del lenguaje de consultas estndar, SELECT, y de paso, a unos cuantos amigos suyos sin los cuales no podra hacer nada. Tenemos en nuestras manos las herramientas suficientes para satisfacer la mayora de los interrogantes que le podemos plantear a los datos de nuestras tablas. Ahora solamente nos resta jugar con estas herramientas y exprimir su posibilidades y su potencia. Recordar que junto con la revistas disponis de tres ficheros en los que apoyaros para realizar los juegos que antes comentbamos. El primero, con la base de datos que nos ha servido de ejemplo durante todo el artculo y sobre la que hemos basado muchas de las explicaciones, y los otros dos con propuestas de consultas que abarcan todos los apartados que hemos tratado y sus correspondientes soluciones. Como se suele hacer en estos casos, recomendaros que primero intentis resolver vosotros solos los problemas que se os plantean y despus miris las soluciones, y como siempre, lo haris al revs, pero en fin, yo tambin lo hara. En el prximo nmero continuaremos con SQL embarcndonos esta vez en las consultas anidadas, que se trata de pasarle a una consulta el resultado de otra consulta y que estos datos devueltos por la primera de todas, la subconsulta, sirva a la segunda para satisfacer una serie de condiciones impuestas. Adems conoceremos las vistas y los procedimientos almacenados. Todo un mundo nos espera aun. Ha llegado ya el momento de la despedida, como siempre, espero haber sido de ayuda a que conozcis mejor SQL y os emplazo al prximo nmero de la revista SINTESIS donde nos volveremos a encontrar. Un saludo, muchas gracias y hasta pronto.

SQL. Vistas y procedimientos.


scar Javier Segura Amors oscarjsa@hotmail.com

Ya estamos aqu un nmero ms para continuar viendo este maravilloso lenguaje de base de datos que es SQL. Hasta este nmero, a travs de los artculos publicados en los nmeros anteriores de SNTESIS, hemos empezado a conocer SQL, su propsito, su estructura, su utilizacin y sus instrucciones. Con el artculo de hoy llegamos ya al final del camino, aunque no terminaremos de andarlo del todo, por si en el futuro queremos seguir paseando por estos paisajes. Hoy vamos a conocer las vistas y los procedimientos almacenados, intentaremos dar una visin amplia de para qu nos pueden servir, y despus profundizar ya ms en la sintaxis y peculiaridades de ambos. Una buena utilizacin de las vistas y los procedimientos en el gestor de nuestras bases de datos nos va a aportar una mayor sencillez en la programacin de las aplicaciones que van a trabajar con las bases de datos, sobre todo si nos encontramos en estructuras cliente/servidor y si a una misma base de datos se le ataca desde aplicaciones diferentes. Vamos a conseguir optimizar nuestro trabajo. Tenemos que intentar que la mayora del trabajo que hay que hacer contra la base de datos la realice el gestor de la base de datos en el servidor. No es muy correcto obtener todos los datos del servidor, pasarlos a la aplicacin y una vez que los tenemos ya en la aplicacin analizarlos, tratarlos y quedarnos solamente con los necesarios, con esta poltica estamos produciendo una sobrecarga en la red o en el canal de transferencia de datos utilizado y adems estamos relentizando el funcionamiento de nuestra aplicacin. Hay que intentar distribuir el trabajo entre los diferentes elementos que conforman nuestro sistema informtico, haciendo que cada uno de ellos cumpla con los cometidos para los que existe y para los que por tanto est preparado. El gestor de la base de datos tienen la razn de ser, no solamente para mantener la base datos y atender nuestras peticiones de informacin, sino tambin para desahogar el funcionamiento de los clientes, y eso lo tenemos que tener muy claro. En el artculo de este nmero, a travs de las vista y los procedimientos vamos a ver como podemos eliminar cierta programacin del cliente y situarla sobre el servidor, optimizando as nuestro trabajo y consiguiendo una aplicacin ms rpida, y ms fcil de mantener y acturalizar. Programacin referida no solamente al anlisis y tratamiento de los datos, sino tambin a la seguridad e integridad de los mismos.

Vistas
Una vista es una consulta almacenada, una estructura SELECT permanente dentro de la base de datos. Permanente desde el momento que se crea hasta el momento que se elimina, si ste ltimo llega a producirse. Tanto la creacin como el borrado de la vista depende del administrador de la base de datos, o en su defecto, del usuario de la misma. Los datos que la vista devuelve, es decir, los datos que forman el dominio de la consulta, se van a conformar en lo que podramos denominar una tabla virtual; tabla, porque vamos a poder trabajar con esos datos como si pertenecieran a una tabla ms de nuestra base de datos, pudiendo sobre ellos realizar inserciones, borrados, actualizaciones, incluso consultas, y virtual porque en realidad no es una tabla propiamente dicha de nuestra base de datos aunque podamos trabajar con ella como tal. Las vistas, principalmente las vamos a utilizar para las siguientes funciones:

Restringir al usuario a filas concretas de una tabla. Por ejemplo, hacer que un empleado slo vea las filas que guardan sus datos en una tabla de seguimiento de actividad laboral sin que pueda ver los datos del resto de compaeros. Restringir al usuario a columnas especficas. Por ejemplo, en la tabla de personal donde tenemos todos los datos de cada trabajador mostrar solamente los referentes a nombre, direccin, telfono y e-mail, no mostrando los datos ms sensibles, permitiendo acceder solamente a esos datos a empleados con un grado de responsabilidad y mando superior, haciendo esto posible a travs de otra vista o dando los permisos pertinentes para que ste pueda trabajar con la tabla de personal directamente. Combinar columnas de varias tablas de forma que parezcan una sola. Por ejemplo, para usuarios noveles facilitarles el trabajo con las consultas o para no permitir que conozcan plenamente la estructura de la base de datos. Agregar informacin en lugar de presentar los detalles. Por ejemplo, presentar la suma de una columna, su valor mximo o mnimo en lugar de presentar todos los valores individuales. Dejar de forma permanente hechas las consulta ms usuales de los usuarios para que las puedan ejecutar de forma rpida, evitando de esta forma, que tengan que teclear cada das las mismas consultas o recuperarlas de un fichero de scripts de SQL. Filtrar la insercin de nuevos datos en la base de datos o filtrar las modificaciones de los ya existentes de forma que solamente se pueda trabajar con un subconjunto definido de los datos. Por ejemplo que el personal del departamento de publicidad solamente pueda trabajar con los datos de aquellos trabajadores que en la tabla de contratos aparecen contratados para dicho departamento. Por motivos de seguridad. Podemos generar vistas que den acceso a subconjuntos de tablas o columnas de nuestra base de datos y despus asignar a cada usuario permisos para poder utilizar determinadas vistas. De esta forma estamos ofreciendo a cada tipo de usuario acceso exclusivamente a los datos que les hacen falta evitando de as que un usuario pueda ver o trabajar con datos que en principio l no tendra que conocer o poder modificar.

Creacin de vistas (CREATE VIEW)


Crear una vista es tan sencillo como crear la consulta que queremos que almacene dicha vista, anteponiendo la clusula CREATE VIEW. La sintaxis para la creacin es:
CREATE VIEW nombre_vista [(columna1, ..., columnaN)] AS SELECT expresin FROM tabla1, ..., tablaN, vista1, ..., vistaN [WHERE expresin] [GROUP BY [ALL] expresin1, ..., expresinN] [HAVING condicin] [WITH CHECK OPTION]

Una vez que hemos creado la vista, los datos que la consulta devuelve se convierten en una tabla, como anteriormente explicaba, cuyo nombre es el nombre que le hemos asignado a la vista y por lo tanto podemos hacer referencia a ella utilizando el nombre de la misma. Por ejemplo, si quisiramos ver todos los datos que devuelve la vista, simplemente tenemos que hacer una consulta, y dicha consulta la hacemos como si la hiciramos para una tabla cualquiera.
SELECT * FROM nombre_vista

A continuacin profundizaremos en cada apartado de la estructura de la creacin de la vista.

El nombre de la vista debe de cumplir las reglas de los identificadores. Especificar el nombre del propietario de la vista es opcional. Las columnas son los nombres que se van a utilizar para las identificar a las columnas de la vista. Asignar un nombre a una columna slo es necesario cuando la columna se derive de una expresin aritmtica, una funcin o una constante, cuando dos o ms columnas pueden tener el mismo nombre, debido normalmente a una combinacin, o cuando la columna de la vista recibe un nombre distinto al de la columna de la que se deriva. Los nombre de las columna las podemos asignar tambin en la consulta, tras la clusula SELECT como se hace en las consultas, sin nos resulta ms sencillo. Si no especificamos ningn nombre a las columnas, estas adquirirn el nombre de la columna de la que se derivan.

? ?

Tras el comando AS escribiremos la consulta que almacenar la vista. En la instruccin SELECT definimos la vista. Podemos utilizar consultas sencilla o complejas, con una tabla o con varias, podemos trabajar tambin con otras vistas utilizndolas como simples tablas, las nicas restricciones que tenemos, las nicas cosas que no podemos utilizar en las consultas que definen una vista es la utilizacin de las clusulas ORDER BY, COMPUTE o COMPUTE BY, la utilizacin de la palabra clave INTO y hacer referencias a tablas temporales. El argumento WITH CHECK OPTION exige que todas las instrucciones de modificacin de datos ejecutadas contra la vista cumplan los criterios establecidos en el apartado SELECT. Si nosotros estipulamos en la consulta una serie de condiciones, en el futuro, a la hora de realizar alguna actualizacin de los datos, bien sea modificndolos o insertando datos nuevos, no podremos llevarla a cabo si dicha actualizacin no supera las condiciones establecidas. Es una buena forma de filtrar las modificaciones e inserciones en nuestras tablas, de forma que controlamos sobre que subdominios de datos del dominio original de la tabla el usuario puede trabajar.

Con el argumento WITH CHECK OPTION hay que tener un poco de cuidado. Imaginemos la situacin de una empresa donde existen dos administrativos, uno dedicado exclusivamente a las cuentas de grandes clientes y otro dedicado a las cuentas de clientes pequeos y medianos, la clasificacin se establece en funcin del volumen de compra anual que dichos clientes nos realizan. Para que cada uno de los administrativos tenga acceso solamente a los datos de los clientes con los que tienen que trabajar, una solucin, es crear dos vistas, una vista trabajar con los clientes cuya compra anual sea superior a una cierta cantidad y la otra vista trabajar con el resto de clientes. De esta forma no tenemos que crear dos tablas de clientes diferentes, la estructura de la base de datos no se tiene que modificar. Si un da el administrativo que se ocupa de los grandes clientes no puede ir a trabajar y hace falta dar de alta a un nuevo gran cliente, se puede ocupar el otro administrativo, pero qu ocurrir?. Pues muy sencillo, cuando el segundo administrativo de alta al nuevo cliente y quiera comprobar sus datos, ste no le aparecer por ningn sitio, y si intenta volver a darle de alta, el sistema le dir que ya existe, para volverse loco!, pensar, y como siempre terminar culpando al informtico. Qu ha ocurrido?, el alta del nuevo cliente se ha realizado sin ningn problema, ya est introducido en la base de datos, pero como el administrativo trabaja con la tabla de clientes a travs de una vista, y esta le muestra solamente un subconjunto de los datos, a l le parece que no ha conseguido introducir al nuevo cliente. Veamos cuales podran ser las vistas de esta situacin.
CREATE TABLE CLIENTES( CODIGO INTEGER NOT NULL, NUM_IDEN_FISCAL VARCHAR(10) NOT NULL, NOMBRE VARCHAR(40), DIRECCIN VARCHAR(80), CIUDAD VARCHAR(30), TELEFONO VARCHAR(9), COMPRA_ANUAL INTEGER, CONSTRAINT CP_CLIENTES PRIMARY KEY (CODIGO),

CONSTRAINT CALT_CLIENTES UNIQUE KEY (NUM_IDEM_FISCALN), CONSTRAINT CAJ_CLIENTES FOREING KEY (COMPRA_ANUAL) REFERENCES (PREVISIONES) ) CREATE VIEW VISTA_CLIENTES_GRANDES AS SELECT * FROM CLIENTES WHERE COMPRA_ANUAL >= 10000000 CREATE VIEW VISTA_CLIENTES_PEQUEOS AS SELECT * FROM CLIENTES WHERE COMPRA_ANUAL < 10000000

Para evitar la situacin que he descrito podramos haber utilizado el argumento WITH CHECK OPTION. Si creamos las vista utilizando este argumento, estamos obligando a que en el futuro cuando queramos realizar una modificacin o una insercin, stas van a tener que cumplir los criterios establecidos en la vista. En el ejemplo concreto, si la hubiramos utilizado, el administrativo al intentar dar de alta al cliente no hubiera podido, puesto que el administrativo va a realizar la insercin contra la vista de clientes pequeos por lo que el cliente no va a satisfacer la condicin impuesta en el campo de COMPRA_ANUAL. Como no se haba establecido el argumento de chequeo, la insercin se puede realizar perfectamente, pero a la hora de comprobar los datos, el nuevo dato no aparecer, no porque no exista, sino porque la vista no lo tiene que mostrar. En nuestro caso, cuando el administrativo de los clientes grandes se vuelva a incorporar al trabajo y ejecute su vista podr comprobar que efectivamente su compaero si que haba insertado al nuevo cliente, por ms que ste le repita que no entiende lo que ha sucedido porque l no consegua el da anterior verlo y al final le terminar costando el puesto al informtico.

Borrado de vistas (DROP VIEW)


Para eliminar una vista, o varias, utilizamos la clusula DROP VIEW, que se usa de una forma tan sencilla como:
DROP VIEW nombre_vista1, ... , nombre_vistaN

Cuando borramos la vista, lo nico que se elimina es sta, es decir, las tablas o vistas con las que estaba relacionada permanecen intactas y podemos continuar utilizndolas sin ningn problema. No sucede lo mismo si lo que hacemos es borrar una tabla o vista que era utilizada por otra vista. Cuando se da esta situacin nos pueden ocurrir dos cosas, dependiendo del sistema gestor de bases de datos que utilicemos:
?

Si utilizamos SQL Server, por ejemplo, al borrar la tabla, la vista que la utilizaba permanecer intacta, pero al intentar utilizar la vista, el gestor nos devolver un mensaje de error indicando que alguna de las tablas que se utilizan en la vista ya no estn disponibles, por lo que no podremos trabajar con ella, no tiene fuente de datos de obtener los resultados. Al no haberse borrado la vista, ya que simplemente se queda inutilizada, si volvemos a crear la tabla, podremos volver a utilizar la vista sin ningn problema. Aqu solamente hay que tener la precaucin de crear la tabla con el mismo nombre y como mnimo, con los mismos campos que se utilizan en la vista.

Si utilizamos Interbase 6, por ejemplo, al intentar borrar la tabla, el gestor nos devolver un mensaje de error indicndonos que no podemos borrar la tabla porque hay algn elemento

asociado a sta, tendremos previamente que borrar la vista, para a continuacin poder borrar la tabla. Las dos polticas que se utilizan cuando se da la situacin de borrar una tabla que tiene asociada una vista son las descritas en los puntos anteriores. Hemos citado el ejemplo de dos gestores concretos, pero el resto de gestores se acogen a uno de los dos funcionamientos mencionados. Continuando con el ejemplo del apartado anterior, podramos borrar las dos vistas incluso simultneamente:
DROP VIEW vista_clientes_grandes, vista_clientes_pequeos

Procedimientos almacenados
Un procedimientos podramos decir que es una evolucin de las vistas, imaginemos una vista que admitiese parmetros para poder acotar la consulta de forma dinmica, pues ya tenemos un procedimiento. Los procedimientos almacenados de SQL son similares a los procedimientos de otros lenguajes de programacin en el sentido de que puede:
? ?

Aceptar parmetros de entrada y devolver varios valores en forma de parmetros de salida. Contener instrucciones de programacin que realicen operaciones en la base de datos, incluidas las llamadas a otros procedimientos. Devolver un valor de estado para indicar si la operacin se ha realizado correctamente o ha habido algn error.

Los procedimientos almacenados tienen ventajas e inconvenientes, como todo en esta vida. Las ventajas:
?

Ayudan a mantener la consistencia de la base de datos. Si dejamos al usuario que campe a sus anchas con las instrucciones de actualizacin, UPDATE, INSERT y DELETE, corremos el riesgo que no siempre se cumplan las reglas de consistencia. Una forma de evitarlo es trabajando las actualizaciones a travs de procedimientos, puesto que tenemos un control de cmo se va a realizar ese proceso. Reducen el trfico en la red. Los procedimientos se ejecutan en el servidor por lo que no tenemos que recibir tablas enteras de datos para realizar despus nuestros anlisis, el anlisis de los datos se ha realizado ya en el servidor y nosotros recibimos simplemente los datos que necesitamos. Ahorramos tiempo de desarrollo. Es normal que en una estructura cliente-servidor varias aplicaciones trabajen con la misma base de datos Si programamos en la propia base de datos las reglas de consistencia nos ahorramos tener que repetir la misma programacin en las distintas aplicaciones, con lo que tambin disminuimos las posibilidades de errores u olvidos de reglas. Si creamos procedimientos almacenados que son utilizados por una o varias aplicaciones, es ms fcil, llegado el momento, cambiar la programacin del procedimiento que cambiar la programacin de la totalidad de las aplicaciones. Ejecucin ms rpida puesto que el procedimiento es compilado y optimizado en el momento de su creacin y despus podemos utilizarlo ya directamente tantas veces como queramos. Si por el contrario utilizamos lotes de comandos de SQL, cada vez que los utilizamos se tienen que compilar y optimizar.

Creacin de procedimientos (CREATE PROCEDURE)


Para la creacin de un procedimiento utilizamos la clusula CREATE PROCEDURE, pero dependiendo del gestor que vayamos a utilizar encontramos unas pequeas diferencias. Vamos a ver la sintaxis para SQL Server e Interbase, por coger dos de los ms utilizados.
Para SQL Server CREATE PROCEDURE nombre_procedimiento [@variable1 tipoDato, ... , @variableN tipoDato [OUTPUT]] AS Instrucciones SQL Para Interbase CREATE PROCEDURE nombre_procedimiento [ (variable_entrada1 tipoDato, ..., variable_entradaN tipoDato)] [ RETURNS (variable_salida1 tipoDato, ..., varialbe_salidaN tipoDato) ] AS [ DECLARE VARIABLE variable_local1 tipoDato; DECLARE VARIABLE variable_localN tipoDato; ] BEGIN Instrucciones SQL END

El nombre_procedimiento es el nombre del nuevo procedimiento almacenado, utilizaremos este nombre cada vez que queramos referirnos a l, bien sea para ejecutarlo o para borrarlo. Los nombre de procedimientos deben seguir las reglas de los identificadores y deben de ser nicos en la base de datos. Las variables, son los parmetros del procedimiento. Cuando creamos un procedimiento podemos declarar una o varias variables y cuando ejecutamos el procedimiento el usuario debe de asignar los valores correspondientes a dichas variables y en el orden en las que estas han sido declaradas. En SQL Server el nombre de las variables siempre empieza por el signo @, no siendo as en Interbase. Las variables son locales al procedimiento por lo que podemos declarar variables con el mismo nombre en procedimientos diferentes. El tipoDato en la declaracin de una variable es el dominio de dicha variable. Los procedimientos pueden devolver valores a la ejecucin del mismo. La devolucin de estos valores, que no sern ms que variables, se deben de indicar en el momento de la declaracin de las mismas. Aqu encontramos otra diferencia de sintaxis entre gestores, en SQL Server se debe de utiliza la clusula OUTPUT al lado de la variable que queremos que retorne su valor, y en Interbase, este tipo de variables deben de declararse separadas de las variables de entrada y despus de la clusula RETURNS. Salvo las diferencias sintcticas es exactamente lo mismo. AS son las acciones que va a llevar a cabo el procedimiento. DECLARE VARIABLE, nos sirve para poder declarar variables locales para utilizar en el bloque de instrucciones SQL. Instrucciones SQL son las instrucciones de SQL que se incluirn en el procedimiento. Aqu existe alguna limitacin, no todas las clusulas de SQL tienen cabida aqu, depende de cada gestor de bases de datos exactamente que instrucciones son aceptadas y cuales no y en qu forma se aceptan. De forma predeterminada, los parmetros admiten el valor NULL. Si se pasa una valor de parmetro como NULL y ese parmetro se utiliza en una instruccin CREATE o ALTER TABLE que hacer referencia a una columna que no admite valores NULL, se generar un error.

Principales instrucciones SQL permitidas en los procedimientos


A continuacin vamos a comentar las principales instrucciones de SQL que son soportadas en los procedimientos. Como ya hemos podido comprobar anteriormente en la creacin del procedimiento, pueden existir diferencias entre los distintos gestores de bases de datos, yo voy a centrarme en Interbase, aunque las diferencias con otros gestores en la mayora de las instrucciones es nula o mnima.
?

Asignaciones a las variables de expresiones. Las variables sern cualquiera de las declaradas en la creacin del procedimiento.
Variable = Expresion

Llamadas a procedimientos, con la precaucin de que no se admiten expresiones en los parmetros


execute procedure nombre_procedimiento [ parametros de entrada ] [ returning_values parametros de salida ]

Condicionales
if (condicin) then instruccin [ else instruccin ]

Bucles controlados por condicin


while (condicin) do instruccin

Instrucciones SQL. Podemos incluir cualquier condicin de manipulacin de datos. Estas instrucciones pueden utilizar variables locales y parmetros, siempre que stas estn precedidas de dos puntos :, para que se puedan diferenciar las variables y parmetros de los nombres de columnas.
update nominas set monto = monto * :plus where comisiones > 10000;

Se pueden utilizar instrucciones select siempre y cuando devuelvan una sola fila, para instrucciones ms generales utilizaremos la instruccin for. Si queremos transferir valores a variables o parmetros lo haremos con la clusula into.
select nombre from clientes where codigo = 23445 into :nombre_empresa; ?

Iteracin sobre consultas. Recorremos el conjunto de filas definido por la instruccin select. Para cada fila, transfiere los valores a las variables de la clusula into, de forma similar a lo que sucede con las selecciones nicas, y ejecuta entonces la instruccin de la seccin do.
for instruccion_select into variables do instruccin

Instrucciones de control. La instruccin exit termina la ejecucin del procedimiento actual. La instruccin suspend, se utiliza con procedimientos que devuelven un conjunto de filas a la rutina que lo ha llamado, suspende temporalmente el procedimiento, hasta que la rutina que lo llama haya procesado los valores retornados.
exit; suspend;

Borrado de procedimientos (DROP PROCEDURES)


Para eliminar uno o ms procedimientos almacenados utilizamos la clusula DROP PROCEDURE:
DROP PROCEDURE procedimiento1, ... , procedimientoN

Ejecucin de procedimientos (EXECUTE)


Para ejecutar un procedimiento..., as de sencillo:
EXECUTE PROCEDURE nombre_procedimiento [parmetro1, ... , parmetroN]

Si no tenemos muchas ganas de escribir, en lugar de EXCUTE podemos utilizar EXEC y a continuacin los valores que queremos darle a los parmetros. Recordar que los valores de los parmetros tienen que pasarse al procedimiento en el mismo orden en el que han sido definidos en el momento de la creacin del mismo.

El carcter de terminacin (SET TERM)


Si vamos a introducir los procedimientos almacenados en la base de datos a travs de un fichero script es necesario que utilicemos un carcter de terminacin para que la aplicacin que vayamos a utilizar para tal fin sepa diferenciar cuando termina un bloque de instrucciones y comienza otro. El carcter de terminacin lo establecemos nosotros a travs de la clusula SET TERM.
SET TERM terminador

El carcter terminador por defecto es el punto y coma ;, ahora bien, en los procedimientos tenemos que introducir los bloques de instrucciones SQL, por lo que aparecern caracteres de terminacin que pertenecen a los diferentes apartados del bloque de instrucciones pero no indican que ha terminado el procedimiento. Sin embargo la aplicacin que utilicemos para introducir el script tomar estos terminadores como marcas de que ha terminado el procedimiento almacenado. Este es el motivo de tener que cambiar el carcter de terminacin. Como carcter terminador tendremos que escoger uno que no vayamos a utilizar en el resto del script, normalmente se utiliza el acento circunflejo ^.
SET TERM ^ ;

Como el cambiar el carcter de terminacin tambin es una instruccin de SQL, tendremos que ponerle el punto y coma ;, seal de que termina. De ahora en adelante, hasta que lo volvamos a cambiar, cada instruccin que escribamos ir finalizada por ^. Para reponer todo a su sitio y dejarlo como ha sido siempre tendremos que volver a cambiar el carcter de terminacin.
SET TERM ; ^

Fin (THE END)


Ya hemos dado un paseo por las vistas y los procedimientos almacenados. Espero que compartis la idea de la distribucin del trabajo que apuntaba en la introduccin del artculo, y que al igual que yo,pensis que

cada elemento del sistema informtico tiene una funcin, y que tenemos que hacerla servir para un mejor funcionamiento general. Un saludo y hasta pronto. scar J. Segura Amors oscarjsa@hotmail.com

Anda mungkin juga menyukai