Beruflich Dokumente
Kultur Dokumente
El directorio puede variar, por ejemplo, puede estar localizado en la raz del disco (C:), o en cualquier
otro lugar donde podamos haber instalado POSTGRES SQL. Para acceder a la consola de
POSTGRES SQL en Windows tendremos que estar situados dentro de ese directorio.
Para el efecto utilizaremos el PostgrSQL 9.1 (x86) el cual al ser instalado se ubica en:
C:\Program Files (x86)\PostgreSQL\9.1\bin>_
En Linux, por supuesto, tambin se puede acceder a PostgreSQL por lnea de comandos.
Posiblemente desde cualquier directorio podamos acceder a la consola de Postgres, sin necesidad de
situarse en el directorio donde est instalado.
Lo primero que tendremos que hacer es conectar con el sistema gestor de Postgres. Para ello,
simplemente tenemos que escribir el comando "psql" e indicarle unas opciones de conexin.
% psql
Con esa sentencia se conecta uno con la base de datos con los parmetros por defecto. Es decir, al
servidor local, con usuario y password.
Lo ms normal es que tengamos que indicar algn otro dato para conectar con la base de datos, como
el usuario, la clave o la direccin del servidor con el que queremos conectar. La sintaxis sera la
siguiente:
Si deseamos conectarnos a la base de datos en local y con nombre de usuario postgres tendramos que
escribir:
% psql -U postgres
Lo primero que nos preguntar ser el password para el usuario postgres. Una vez introducida la
clave, ya estaremos dentro de la lnea de comandos de PostgreSQL. Con ello el prompt cambiar a
algo como esto:
postgres=#
Lo ms normal es que necesites conectarte con una base de datos en concreto, de entre todas las que
puedes tener creadas en tu servidor PostgreSQL. Eso se hace con el comando \c, seguido del nombre
de la base de datos que deseas conectar.
postgres=# \c mibasedatos;
mibasedatos =#
ATENCIN: Hay que fijarse que todas las sentencias dentro de la lnea de comandos de PostgreSQL
acaban en ";" a excepcin \caracter. Si no colocamos el punto y coma, lo ms seguro es que NO se
ejecute el comando y nos vuelva a salir el prompt para que sigamos introduciendo el comando. Si lo
que queramos era ejecutar la sentencia que habamos escrito antes, con simplemente entrar el ";"
ser suficiente. Es decir, no debemos escribir de nuevo la sentencia entera, slo el ";" y volver a
apretar "enter".
Si queremos ver una lista de las bases de datos alojadas en nuestro servidor podemos escribir el
comando \l. As:
postgres=# \l
Con esto nos mostrara una lista de las bases de datos de nuestro servidor. Algo como esto:
postgres=# \l
Si queremos crear una base datos, podremos hacerlo con el comando "create database" seguido del
nombre de la nueva base de datos.
postgres=# create database miprueba;
Lgicamente, esta base de datos recin creada estar vaca, pero si estuviramos usando una base de
datos ya creada y queremos ver las tablas que tiene escribiramos el comando "\dt".
postgres=# \dt Lista solo tablas
postgres=# \d Lista tablas y vistas
Si no hay tablas, nos dir algo como " No se encontraron relaciones.", pero si tenemos varias tablas
dadas de alta en la base de datos que estamos usando, nos saldr una lista de ellas:
miprueba=# \dt;
Ahora, si deseamos obtener informacin sobre una tabla, para saber qu campos tiene y de qu tipo,
podremos utilizar el comando \d seguido del nombre de la tabla.
miprueba=# \d estudiantes;
En este apartado se resumen las principales sentencias SQL que pueden ser utilizadas en el gestor de
base de datos PostgreSQL.
CREACIN DE TABLAS
Una tabla es utilizada para organizar y presentar informacin. Las tablas se componen de filas y
columnas de celdas que se pueden rellenar con informacin, las tablas se componen de dos
estructuras:
Registro: se la podra definir como una fila que contiene datos de los mismos
tipos que las dems filas. Ejemplo: en una tabla que tiene columnas como
nombres y direcciones, cada fila contendr un nombre y una direccin.
Campo: es cada una de las columnas que forman la tabla. Contienen datos de
tipo diferente a los de otros campos. En el ejemplo anterior, un campo contendr
un tipo de datos nico, como una direccin, o un nmero de telfono, un nombre,
etc.
3 Ing. Gabriel Demera Ureta MgSc.
Aplicaciones de Base de Datos
Cada tabla creada debe tener un nombre nico en la cada Base de Datos, hacindola accesible
mediante su nombre o su seudnimo (Alias). Las tablas son los objetos principales de bases de datos
que se utilizan para guardar gran cantidad de datos.
Despus de la fase de diseo de una base de datos, en necesario crear las tablas correspondientes
dentro de la base de datos. Para cada campo o columna de cada una de las tablas, es necesario
determinar el tipo de datos que contiene, para de esa forma ajustar el diseo de la base de datos, y
conseguir un almacenamiento ptimo con la menor utilizacin de espacio. Los tipos de datos que
puede haber en un campo, se pueden agrupar en tres grandes grupos:
timestamp [(p)][without
time zone]
fecha y hora (sin zona horaria)
timestamp [(p)] with
time zone
timestamptz fecha y hora, incluyendo zona horaria
tsquery consulta de bsqueda de texto
tsvector documento de bsqueda de texto
instantnea de ID de transaccin a nivel de
txid_snapshot
usuario
uuid identificador universalmente nico
xml datos XML
Compatibilidad: Los siguientes tipos de datos son especificados por SQL: bigint, bit, bit
varying, boolean, char, character varying, character, varchar, date, double precision,
integer, interval, numeric, decimal, real, smallint, time (con o sin zona horaria), timestamp
(con o sin zona horaria), xml.
Cada tipo de datos tiene una representacin externa determinada por sus funciones de entrada y
salida. Muchos de los tipos de datos incorporados tienen formatos externos obvios. Sin embargo,
varios tipos o son nicos de PostgreSQL, como los caminos geomtricos, o tienen varios formatos
posibles, como los tipos de fecha y hora. Algunas de las funciones de entrada y salida no son
invertibles, por ej., el resultado de una funcin de salida podra perder exactitud cuando se compara
con la entrada original.
TIPOS FECHA:
Postgresql soporta un conjunto completo de tipos SQL de datos de fecha y de hora, demostrado en la
siguiente tabla:
Nota: Antes de la versin 7.3, el escribir solamente timestamp era equivalente a escribir
timestamp with time zone. Esto fue cambiado para compatibilidad con SQL estndar.
time, timestamp, e interval aceptan un valor de presicin opcional p que especifica el nmero de
digitos fraccionales almacenados en el campo de segundos. Por defecto, no hay un valor fijo explcito
en la presicin. El rango permitido de p va desde 0 a 6 para los tipos timestamp e interval.
Nota: Cuando los valores de timestamp son almacenados como enteros de 8 bytes (es el por
defecto), la precisin de microsegundos est disponible para el rango completo de valores. Cuando
los valores timestamp son almacenados como de presicin doble de coma flotante (una opcin en
desuso en tiempo de compilacin), la presicin efectiva lmite es menor de 6. Los valores timestamp
son almacenados con los segundo antes o despus de la medianoche del 2000-01-01. Cuando los
valores timestamp son implementados usando nmeros de coma flotante, la presicin de
microsegundos es acertada para las fechas cercanas al 2000-01-01 y perder presicin para fechas
ms lejanas. Vea que utilizando tipos en coma-flotante permite un rango ms grande de valores que
pueda representar el timestamp mostrado arriba: desde 4713 A.C. hasta 5874897 D.C.
TIPOS DE CADENA:
Los tipos de datos del motor de base de datos gratuito y open source PostgreSQL de tipo carcter
son:
Nombre Descripcin
character varying(n),
De longitud variable, con lmite
varchar(n)
character(n), char(n) De longitud fija
text De longitud variable, ilimitado
Supongamos que se desea crear una tabla de nombre PRUEBA cuya clave primaria es id (campo que
identifica unvocamente a la tabla) que va incrementando su valor automticamente cada vez que
insertamos un nuevo valor en la tabla, un campo nombre que es de tipo cadena de caracteres de
como mximo 60 caracteres y un campo sexo que es de tipo cadena de caracteres:
CREATE TABLE prueba(
ID SERIAL NOT NULL PRIMARY KEY,
NOMBRE VARCHAR(60) DEFAULT NULL,
sexo VARCHAR(1)
);
Otra forma de crearla sera:
CREATE TABLE prueba2(
ID BIGSERIAL NOT NULL,
NOMBRE VARCHAR(60),
sexo VARCHAR(1),
6 Ing. Gabriel Demera Ureta MgSc.
Aplicaciones de Base de Datos
primary key(id)
);
Asumamos que necesitamos crear una tabla y despus se necesitar realizar algunos cambios:
Para cambia solo el tipo de datos de la columna 'edad' y especifica que no admite nulos:
ALTER TABLE usuario ALTER COLUMN edad TYPE decimal (6,2);
\d usuario;
En la tabla 'usuario' cualquiera que sea la columna que tenga 'SERIAL' empezar a autogenerarse de
forma secuencial por el gestor de PostgreSQL, s usted desea cambiar dicha secuencia de forma que
los nuevos registros comiencen a partir de '1000' o cualquier otro nmero, debemos realizar lo
siguiente:
1. Para comprobar la funcionalidad de la secuencia ingresaremos un registro y mostraremos su serie:
INSERT INTO usuario(nombre,direccion,poblacion,edad,fecha_registro,email)
VALUES(Pablo Martinez,ABC,Potoviejo,18,2014/07/10,pmartimez@utm.edu.ec);
SELECT * FROM usuario;
2. Usted debe crear un archivo de secuencia de la siguiente manera
CREATE SEQUENCE id_usuario_seq start 1000;
3. Usted debe modificar la tabla para que utilice en archivo de secuencia
S usted necesita cambiar el valor de secuencia una vez creada la secuencia, usted puede modificar el
valor de la siguiente forma:
SELECT setval('id_usuario_seq',1500,'false');
INSERT INTO usuario (nombre,direccion,poblacion,edad,fecha_registro,email)
VALUES(Ana,Forestal,Potoviejo,28,2014/06/11,abarba@utm.edu.ec);
Otra alternativa para modificar el valor inicial de secuencia podra ser:
ALTER SEQUENCE id_usuario_seq restart 2000;
INSERT INTO usuario(nombre,direccion,poblacion,edad,fecha_registro,email)
VALUES(Mara,Meja,Meja,18,2014/06/09,mperez@utm.edu.ec);
SELECT * FROM usuario;
Para eliminar la columna 'edad' de la tabla 'usuario', usted tendra que realizar lo siguiente:
ALTER TABLE usuario DROP COLUMN edad;
\d usuario;
Renombrar la tabla
ALTER TABLE Usuario RENAME TO acceso;
\dt
Para ejemplificar la creacin de una base de datos con sus respectivas tablas, tomaremos como
referencia el almacenamiento de registros datos para una unidad educativa, para el siguiente anlisis
considere que un alumno puede ser con el tiempo ser un padre de familia, o un docente de la misma
institucin:
\c Unidad;
);
CREATE TYPE sex AS ENUM ('M', 'F');
CREATE TYPE ec AS ENUM ('S','C','D','V','U');
Los datos registrados pueden ser extrados de la tabla mediante el uso de la instruccin SELECT , por
ejemplo, si se necesita el listado se todas las personas con todos sus datos podramos hacerlo de la siguiente
forma:
SELECT IdPersona, ApellidoPaterno, ApellidoMaterno, Nombres, Direccion, telefono, sexo, FechaNacimiento,
EstadoCivil FROM personas;
Cuando se desea omitir el listado de todos los campos y obtener el mismo resultado usted puede hacer uso del
asterisco (*), por ejemplo:
SELECT * FROM personas;
Cuando se desea datos especficos usted puede utilizar de la lista de campos los que desee, por ejemplo, listar
los apellidos, nombres, direcciones y fechas de nacimiento de todos los ingresados:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, Direccion, FechaNacimiento FROM personas;
S lo solicitado incluye la condicin de que solo sea para los de sexo femenino, se debe incluir la clusula
WHERE que permite agregar condiciones de clasificacin de datos, por ejemplo:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, Direccion, FechaNacimiento
FROM personas
WHERE sexo=F;
Si necesitamos la lista de personas mayores de 30 aos de edad, se tendra que conocer la fecha de
hoy asumamos que es 18 de agosto de 2013, si resto 30 aos quedara 1983/09/18 (este es el formato
de PostgreSQL), as que la instruccin quedara:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, telefono, sexo, FechaNacimiento
FROM personas
WHERE FechaNacimiento <1983/09/18;
Podemos cambiar los formatos de salida que se utilizan en PostgreSQL, por ejemplo, mostraremos
unidos los apellidos y el nombre, fecha de nacimiento con el formato da mes y ao, y sexo mostrar
masculino o femenino:
SELECT concat(personas.ApellidoPaterno, ' ',personas.ApellidoMaterno ,' ',personas.Nombres) As Estudiante, CASE
sexo WHEN 'F' then 'Femenino' ELSE 'Masculino' END As Sexo, to_char(FechaNacimiento, 'dd/mm/yyyy') AS
FechaNacimiento
FROM personas;
SELECT (personas.ApellidoPaterno || ' ' || personas.ApellidoMaterno || ' ' || personas.Nombres) As Estudiante, CASE
sexo WHEN 'F' then 'Femenino' ELSE 'Masculino' END As Sexo, to_char(FechaNacimiento, 'dd/mm/yyyy') AS
FechaNacimiento
FROM personas;
S se necesita ver las edades de todas las personas utilizaremos la funcin DATE_PART que
devuelve la diferencia en aos entre dos fechas, la clusula CURRENT_DATE devuelve la fecha
actual que registra el computador:
SELECT concat(personas.ApellidoPaterno, ' ',personas.ApellidoMaterno ,' ',personas.Nombres) As Nombre,
DATE_PART(year,current_date::date) - DATE_PART(year, fechanacimiento::date) as edad FROM personas;
Por defecto ordena ascendentemente o si prefiere puede utilizar la instruccin ASC, tambin puede
incluir sub rdenes agregando una lista separada por comas, por ejemplo:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, telefono, sexo, FechaNacimiento
FROM personas ORDER BY ApellidoPaterno ASC, ApellidoMaterno DESC;
Asumiendo que necesitamos las tres personas que tengan ms edad podramos utilizar:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, sexo, FechaNacimiento
FROM personas ORDER BY FechaNacimiento ASC LIMIT 3;
Para obtener un listado de aos de nacimiento sin que se repitan tendramos que realizar lo siguiente:
SELECT DISTINCT extract(year from FechaNacimiento) AS anio
FROM personas ORDER BY anio;
A menudo tenemos columnas que son cadenas de caracteres, y queremos buscar las cadenas que
contienen cierta palabra. Esto se realiza a travs de un nuevo tipo de condicin:
Nombre_de_columna LIKE cadena_de_caracteres.
Con LIKE puede usar los siguientes dos caracteres comodines en el patrn:
Carcter Descricin
% Coincidencia de cualquier nmero de caracteres, incluso cero caracteres
_ Coincide exactamente un carcter
Si se necesita listar todas las personas cuyo apellido paterno no empiece con Z entonces quedara as:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, sexo, FechaNacimiento
FROM personas
WHERE ApellidoPaterno NOT LIKE Z%;
Para testear instancias literales de un carcter comodn, preceda el carcter con el carcter de escape.
Si no especifica el carcter ESCAPE , se asume '\' .
Cadena Descricin
\% Coincide un carcter '%'
\_ Coincide un carcter '_'
Si desea filtrar registros utilizando una lista de valores o palabras puede hacer uso de la clusula IN,
por ejemplo asumamos que queremos ver la lista de personas cuyo apellido paterno es VACA,
PANTA y SALAZAR tendramos que hacer lo siguiente:
En algn momento necesitaremos consultas que nos devuelva totales (1 solo registro), para ello se
utilizar unas funciones estandarizadas de clculo de registros COUNT(), SUM(), AVG(), MAX(),
NIM(), entre otros.
Existe la posibilidad de utilizar agrupamientos para que puedan existir varios totales dependiendo de
las necesidades de agrupar, para esto se utiliza la clusula GROUP BY
Para conocer cuntas personas nacieron por ao de las que se encuentran registradas en nuestra tabla
podramos realizar lo siguiente:
SELECT CASE estadocivil WHEN 'C' then 'CASADO' WHEN 'S' then 'SOLTERO' WHEN 'D' then 'DIVORCIADO'
WHEN 'V' then 'VIUDO' ELSE 'UNION LIBRE' END As Estado_Civil, count(*) As Total_de_Personas
FROM personas
GROUP BY estadocivil;
LAS SUBCONSULTAS
Una subconsulta, es una sentencia SELECT que aparece dentro de otra sentencia SELECT que
llamaremos consulta principal. Se puede encontrar en la lista de seleccin, en la clusula WHERE
o en la clusula HAVING de la consulta principal.
Una subconsulta tiene la misma sintaxis que una sentencia SELECT normal exceptuando que aparece
encerrada entre parntesis, no puede contener la clusula ORDER BY, ni puede ser la UNION de
varias sentencias SELECT, adems tiene algunas restricciones en cuanto a nmero de columnas
segn el lugar donde aparece en la consulta principal.
Cuando se ejecuta una consulta que contiene una subconsulta, la subconsulta se ejecuta por cada
fila de la consulta principal.
Las consultas que utilizan subconsultas suelen ser ms fciles de interpretar por el usuario.
Para realizar las siguientes prcticas agregaremos ms registros a las tablas Personas y Profesores:
INSERT INTO Personas
(ApellidoPaterno,ApellidoMaterno,Nombres,Direccion,telefono,sexo,FechaNacimiento,EstadoCivil)
VALUES ('Falcones','Canchingre','ngela', 'Cdla. Los tamarindos', '052636456','F','1982/06/18','C'),
('Mora', 'Hidalgo', 'Octavio', 'Cdla. Ceibos del Norte','052360789','M','1970/05/08','C'),
('Delgado', 'Ramirez', 'Maricela', 'Cdla. Ceibos del Norte','054511133','F','1996/08/12','C'),
('Zambrano','Delgado', 'Javier', 'Cdla. Los Bosques', '052456123','M','1984-05-28','D'),
('Cardenas','Flores', 'Ana Mara', 'Eloy Alfaro y Plaza', '052100456','F','1991-03-18','D'),
('Basurto', 'Cedeo', 'Dolores', 'Cdla. Los Mangos', '052390987','F','1971/04/01','C'),
('Zambrano','Lpez', 'Jos', 'parroq. San Placido', '052111654','M','1973/03/30','C'),
('Montesdeoca','Ureta','Elena ', 'Cdla. Forestal', '052222321','F','1974/01/25','C'),
('Faras', 'Salazar', 'Joel', 'Cdla. Terra Nostra', '052333254','M','1979/08/13','C'),
('Delgado', 'Manuel', 'Benedicto', 'Cdla. Los Bosques', '052444157','M','1979/09/23','C'),
('Navarrete','Ormaza', 'Yolanda', 'Cdla. Los tamarindos', '052534876','F','1981/01/10','C'),
('Giler', 'Meja', 'Scrates', 'Cdla. Ceibos del Norte','052778654','M','1985/03/18','C'),
('Mendieta','Vera', 'Juan Carlos','No Registrada', '052580505','M','1974/05/18','C'),
('Brines', 'Zambrano','Gema', '25 de Diciembre', '052654987','F','1980/04/14','S'),
('Moya', 'Loor', 'Fernando', 'Morales', '052654987','M','1982/09/28','S'),
('Arias', 'De la Cruz','Ivan', 'Ramos y Duarte', '321654987','M','1990/08/25','V'),
('Andrade', 'Castro', 'Viviana ', 'San Placido', '052222233','F','2000/03/01','S'),
('Benitez', 'Sabando', 'Carmen', 'Calderon', '053333233','F','2001/06/30','S'),
('Burbano', 'Vera', 'Jos ', 'Rio Chico', '054444233','M','1995/02/17','S'),
('Zambrano','Cardenas', 'Mara Jos','Cdla. Bosques', '054561233','F','1999/06/10','S'),
('Zambrano','Cardenas','Eduardo', 'Rio Chico', '051111233','M','1995/03/01','S'),
('Zambrano','Falcones','Paola', 'Los tamarindos', '054871233','F','2000/03/18','S'),
('Demera', 'Montero', 'Alejandro', ' Cdla Parque Forestal', '055551233','M','2001/01/20','S'),
('Mora', 'Delgado', 'Miguel ngel','18 de octubre', '056666233','M','2002/03/15','S'),
('Zambrano','Bazurto', 'Leonardo', 'Los Mangos', '057771233','M','2000/08/11','S'),
('Zambrano','Bazurto', 'Enrique ', 'Los Tamarindos', '058888233','M','2002/11/11','S'),
('Faras', 'Montesdeoca','Francisco','Los Bosques', '059999233','M','1996/03/19','S'),
('Delgado','Navarrete','Carlos Luis','San Placido', '050001233','M','2001/12/31','S'),
('Giler', 'Briones', 'LilY Anabel', 'Cdla Forestal', '051112222','F','1990/03/21','S'),
('Mendieta','Andrade', 'Marcos', 'Cdla Primero de Mayo', '051114444','M','1993/10/10','S'),
('Moya', 'Aveiga', 'Antonio', 'Parroquia Calderon', '051115555','M','2000/05/25','S'),
('Arias', 'Benitez', 'John Jairo', 'Va a Rio Chico', '051116666','M','2002/07/30','S'),
('Burbano', 'Moncayo', 'Pedro Andrs','Floron 1', '051117777','M','1998/01/17','S'),
('Demera', 'Montero','Mara Gabriela',' Cdla Parque Forestal','051118888','F','1995/05/09','S'),
('Mora', 'Delgado', 'Virginia Yessenia','Parr. Rio Chico','051119999','F','2001/06/04','S'),
('Zambrano','Falcones','Jos Daniel','San Alejo', '051111000','M','1992/07/15','S'),
('Moya', 'Aveiga', 'David Fabian','18 de octubre', '051111545','M','2000/09/21','S'),
('Giler', 'Briones', 'Fabricio', 'San Placido', '051111129','M','1994/11/12','S'),
('Mendieta','Andrade','Lourdes', 'Km1 va a rocafuerte', '051119876','F','2002/11/03','S'),
('Faras', 'Montesdeoca', 'Junior Jos','Los Angeles', '051115433','M','1998/12/18','S');
Para mostrar el listado de personas que son autoridades en la institucin se lo realizara as:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres
FROM personas
WHERE IdPersona IN (SELECT IdPersona FROM Profesores WHERE cargo <>Profesor);
Para mostrar lo nombres y apellidos de los profesores que son padres de familia en la institucin se lo
realizara as:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres
FROM personas
WHERE IdPersona IN (SELECT IdPersona FROM Padres WHERE ocupacion like Profe%);
Si necesita mostrar la lista de estudiantes cuyas madres sean profesoras de la institucin quedara as:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres
FROM personas
WHERE IdPersona IN (SELECT IdPersona FROM Estudiante WHERE IdPersonaMama IN (SELECT idpersona
FROM Profesores)) ORDER BY ApellidoPaterno;
Las subconsultas permiten comparar, desde la consulta principal con datos extrados desde la misma
u otras tablas, pero no se pueden mostrar los campos de las subconsulta con los campos de la
consulta principal.
CONSULTAS MULTI-TABLAS
Hasta ahora todas las consultas que hemos usado se refieren a mostrar datos de slo una tabla, pero
tambin es posible hacer consultas usando varias tablas en la misma sentencia SELECT.
Este proceso permite realizar dos operaciones de lgebra relacional: el producto cartesiano y la
composicin.
Esto es: si partimos de dos relaciones, R y S, cuyos grados son n y m, y cuyas cardinalidades a y b, la
relacin producto tendr todos los atributos presentes en ambas relaciones, por lo tanto, el grado ser
n+m. Adems la cardinalidad ser el producto de a y b.
Para ver un ejemplo usaremos dos tablas inventadas al efecto:
tabla2
id nmero
15 12345678
26 21222112
15 66525425
tabla1 x tabla2
id nombre apellido id nmero
15 Fulginio Liepez 15 12345678
26 Cascanio Suanchiez 15 12345678
15 Fulginio Liepez 26 21222112
26 Cascanio Suanchiez 26 21222112
15 Fulginio Liepez 15 66525425
26 Cascanio Suanchiez 15 66525425
Composicin (Join).- Una composicin (Join en ingls) es una restriccin del producto
cartesiano, en la relacin de salida slo se incluyen las tuplas que cumplan una
determinada condicin.
La condicin que se usa ms frecuentemente es la igualdad entre dos atributos, uno de cada tabla.
<relacin1>[<condicin>]<relacin2>
tabla2
id nmero
15 12345678
26 21222112
15 66525425
La composicin de estas dos tablas, para una condicin en que 'id' sea igual en ambas sera:
tabla1[tabla1.id = tabla2.id]tabla2
id nombre apellido t2.id nmero
15 Fulginio Liepez 15 12345678
26 Cascanio Suanchiez 26 21222112
15 Fulginio Liepez 15 66525425
Para aplicar el producto cartesiano en consultas multi-tablas crearemos otras entidades a nuestra base
de datos UNIDAD:
INSERT INTO
Matriculas(IdPersonaEstudiante,IdPeriodoLectivo,IdEspecialidad,IdCurso,IdParalelo,IdPersonaRepresentante,Folder)
VALUES (46,2,1,7,1,30,'Archivador A 25'),
(47,2,1,7,1,33,'Archivador A 26'),
(42,2,1,7,1,24,'Archivador A 25'),
(37,2,1,7,1,1, 'Archivador A 26'),
(48,2,1,6,1,2 ,'Archivador A 27'),
(41,2,1,7,1,22,'Archivador A 27'),
(54,2,1,6,1,23,'Archivador A 28'),
(43,2,1,7,1,26,'Archivador A 28'),
(52,2,1,6,1,26,'Archivador A 29'),
(44,2,1,7,1,27,'Archivador A 29'),
(53,2,1,6,1,27,'Archivador A 30'),
(38,2,1,7,1,16,'Archivador A 30'),
(49,2,1,7,1,16,'Archivador A 31'),
(45,2,1,6,1,29,'Archivador A 31'),
(51,2,1,6,1,29,'Archivador A 32'),
(35,2,1,6,1,19,'Archivador A 32'),
(40,2,1,6,1,20,'Archivador A 33'),
(39,2,1,7,1,20,'Archivador A 33'),
(36,2,1,6,1,15,'Archivador A 34'),
(34,2,1,7,1,19,'Archivador A 34');
(Aplicando producto cartesiano con dos tablas) Si se necesita conocer la lista de profesores con sus
datos personales tendramos que hacer lo siguiente:
SELECT concat(ApellidoPaterno, , ApellidoMaterno, ,Nombres) AS Personas, cargo, titulacion
FROM Personas, Profesores
WHERE Personas.IdPersona=Profesores.IdPersona;
(Aplicando producto cartesiano con tres tablas) S necesitamos el listado de estudiantes matriculados
con sus respectivos representantes, tendramos:
SELECT concat(personas.ApellidoPaterno, ,
personas.ApellidoMaterno, , personas.Nombres) As
Estudiantes, Matriculas.IdMatricula As Matricula,
concat(personas_1.ApellidoPaterno, ,
personas_1.ApellidoMaterno, , personas_1.Nombres) As
Representante
FROM Personas AS personas_1, Personas, Matriculas
WHERE
personas.IdPersona = matriculas.IdPersonaEstudiante AND
personas_1.IdPersona = matriculas.IdPersonaRepresentante;
El INNER JOIN es otro tipo de composicin de tablas, permite emparejar filas de distintas tablas de
forma ms eficiente que con el producto cartesiano cuando una de las columnas de emparejamiento
est indexada. Ya que en vez de hacer el producto cartesiano completo y luego seleccionar la filas
que cumplen la condicin de emparejamiento, para cada fila de una de las tablas busca directamente
en la otra tabla las filas que cumplen la condicin, con lo cual se emparejan slo las filas que luego
aparecen en el resultado.
La sintaxis es la siguiente:
tabla1 y tabla2 son especificaciones de tabla (nombre de tabla con alias o no, nombre de consulta
guardada), de las tablas cuyos registros se van a combinar.
Las columnas de emparejamiento deben contener la misma clase de datos, las dos de tipo texto, de
tipo fecha etc... los campos numricos deben ser de tipos similares. Por ejemplo, se puede combinar
campos AutoNumrico y Long puesto que son tipos similares, sin embargo, no se puede combinar
campos de tipo Simple y Doble. Adems las columnas no pueden ser de tipo Memo ni OLE.
comp representa cualquier operador de comparacin ( =, <, >, <=, >=, o <> ) y se utiliza para
establecer la condicin de emparejamiento.
Se pueden definir varias condiciones de emparejamiento unidas por los operadores AND y OR
poniendo cada condicin entre parntesis.
Ejemplo:
Si necesitamos ver el listado de profesores, tendramos:
SELECT personas.ApellidoPaterno, personas.ApellidoMaterno, personas.Nombres, profesores.cargo,
profesores.Titulacion
FROM personas INNER JOIN profesores ON personas.IdPersona = profesores.IdPersona;
Se pueden combinar ms de dos tablas, en este caso hay que sustituir en la sintaxis una tabla por un
INNER JOIN completo.
Por ejemplo, s necesitamos el listado de todos los estudiantes matriculados con sus respectivos
representantes, tendramos:
Las vistas tienen la misma estructura que una tabla: filas y columnas. La nica diferencia es que slo
se almacena de ellas la definicin, no los datos. Los datos que se recuperan mediante una consulta a
una vista se presentarn igual que los de una tabla. De hecho, si no se sabe que se est trabajando con
una vista, nada hace suponer que es as. Al igual que sucede con una tabla, se pueden insertar,
actualizar, borrar y seleccionar datos en una vista. Aunque siempre es posible seleccionar datos de
una vista, en algunas condiciones existen restricciones para realizar el resto de las operaciones sobre
vistas.
Una vista se especifica a travs de una expresin de consulta (una sentencia SELECT) que la calcula
y que puede realizarse sobre una o ms tablas. Sobre un conjunto de tablas relacionales se puede
trabajar con un nmero cualquiera de vistas.
La mayora de los SGBD soportan la creacin y manipulacin de vistas. Las vistas se crean cuando
se necesitan hacer varias sentencias para devolver una tabla final.
CREANDO UNA VISTA: Se emplea la sentencia CREATE VIEW, que incluye una
subconsulta (subquery) para determinar los datos a ser mostrados a travs de la vista.
Sintaxis:
CREATE [OR REPLACE] VIEW <vista>
[(<alias>[, <alias>] )]
AS <subconsulta>;
Dnde: OR REPLACE Se utiliza por si la vista ya estuviera creada anteriormente. En ese caso, la
sustituye por la nueva definicin. Por ejemplo si necesitamos crear una vista que muestra el listado de
profesores:
CREATE VIEW V_Lista_Profesores AS
SELECT ApellidoPaterno, ApellidoMaterno,Nombres, Titulacion
FROM profesores INNER JOIN personas ON profesores.IdPersona = personas.IdPersona
WHERE profesores.cargo Like 'Prof%'
ORDER BY ApellidoPaterno;
Si necesita chequear la creacin de la vista, utilice el comando \dv, para verificar el contenido de la
vista utilice (\d+ V_lista_Profesores;), para ver la vista ejecutada utilice el comando (SELECT *
FROM v_lista_profesores;), asumiendo que la vista tiene fallas, lo ms recomendable es volver a
ejecutar la vista utilizando la sintaxis OR REPLACE, por ejemplo:
Para aplicar una condicin a la vista como si se tratara de una tabla se lo realiza de la siguiente
manera:
SELECT * FROM V_lista_Estudiantes WHERE curso='Septimo' AND paralelo=A;
Es importante entender que los campos a utilizar en la comparacin deben estar en el listado de la
vista.
El siguiente ejemplo se creara 2 vistas para ser utilizadas en una relacin, el resultado consiste en
mostrar la lista de estudiantes cuyos padres sean profesores:
Si queremos probar en acceso con el usuario fci, el gestor le permitir acceder siempre y cuando
especifique la base de datos.
\q
C:\Program Files (x86)\PostgreSQL\9.1\bin> psql -U fci postgres
Los usuarios con accesos limitados tienen el siguiente promptuario (postgres=>), usted podr aplicar
comando de navegacin pero no podr crear ni modificar los datos de las diferentes bases de datos.
S queremos asignarle privilegios al usuario debemos entrar a la base de datos para poderlos aplicar,
para el ejemplo ingresaremos a la base de datos unidad con el usuario postgres:
C:\Program Files (x86)\PostgreSQL\9.1\bin> psql -U postgres unidad
unidad=# GRANT SELECT ON personas TO fci;
Para crear el usuario fc2 con permiso de conexin se lo realizara de la siguiente forma:
CREATE ROLE fci2 WITH PASSWORD 123' LOGIN;
Para eliminar un usuario o un rol se aplica de igual forma apara ambos de la siguiente forma:
DROP ROLE fci2;
DROP USER fci2;
Por ejemplo el siguiente usuario podr crear bases de datos, roles e iniciar replicaciones pero no
podr conectarse al servidor:
CREATE ROLE fci3 CREATEDB CREATEROLE REPLICATION;
\du
PRIVILEGIOS DE LOS OBJETOS EN UNA BASE DE DATOS
Cuando se crean objetos en una base de datos, a estos se les asigna un propietario, este propietario es
el nico que tiene control total sobre el objeto creado, es el nico que puede modificarlo y destruirlo
a gusto propio, es decir puede determinar qu hacer con el objeto y adems, puede asignar privilegios
a los diferentes roles sobre ese objeto.
Para asignar privilegios se usa el comando GRANT que habilita los privilegios en el objeto.
El comando REVOKE, quita los permisos sobre ese objeto.
Por ejemplo para permitir al rol profesor tener privilegios de consulta sobre la tabla Personas, se
puede ejecutar la siguiente sentencia:
GRANT SELECT ON Personas TO profesor;
Existen varios tipos de privilegios que en s son los comandos que ejecutan una accin sobre el
objeto, la siguiente es una lista de los diferentes tipos de privilegios.
Tipos de privilegios:
SELECT Acceso a todas las columnas de una tabla/vista especfica.
INSERT Inserta datos en todas las columnas de una tabla especfica.
UPDATE Actualiza todas las columnas de una tabla especfica.
DELETE Elimina filas de una tabla especfica.
RULE Define las reglas de la tabla o vista.
ALL Otorga todos los privilegios.
La palabra clave ALL se usa para hacer referencia a todos los privilegios.
Cuando se hace referencia al usuario PUBLIC se hace referencia a todos los usuarios.
Si queremos asignar todos los privilegios al rol profesor sobre la tabla PAERSONAS se ejecuta lo
siguiente:
GRANT ALL ON Personas TO profesor;
Al igual si queremos que todos los usuarios tengan acceso a todos los privilegios de la tabla
PERSONAS, se ejecuta lo siguiente:
GRANT ALL ON Personas TO PUBLIC;
Para este ejemplo crearemos un Rol, que agrupe todos los usuarios y no tenga ningn privilegio:
CREATE ROLE Autoridades NOLOGIN;
Ahora crearemos un usuario diferente para cada base de datos con privilegios para insertar/modificar:
CREATE USER Rector IN ROLE autoridades LOGIN ENCRYPTED PASSWORD '123';
CREATE USER Vicerector LOGIN ENCRYPTED PASSWORD '123';
CREATE USER administrador IN ROLE autoridades LOGIN ENCRYPTED PASSWORD
'123';
Note que el usuario Vicerector no se le agrego al rol de autoridades, para solucionar esto usted puede
aplicar la siguiente instruccin:
ALTER GROUP autoridades ADD USER vicerector;
Como ejemplo ahora le quitaremos todos los privilegios sobre la tabla: tabla1 para los usuarios
rector y vicerrector:
REVOKE ALL ON tabla1 FROM rector;
REVOKE ALL ON tabla1 FROM vicerector;
Nota: Considere que se han quitado los privilegios sobre la table ms no sobre la base de datos
Los privilegios pueden agregarlos o quitarlos segn su administracin, ahora se otorgar privilegios de
consulta sobre la tabla tabla1 para el usuario rector
GRANT SELECT ON tabla1 TO rector;
S ejecutamos la instruccin: SELECT * FROM tabla1; de seguro no tendr problemas pero si intenta
insertar un registro como: INSERT INTO tabla1 values (1,Juan); tendr problemas porque no tiene
asignado el privilegio.
Como ejemplo otorgaremos privilegios para insertar datos sobre la tabla tabla1 al usuario
vicerector (requiere privilegios sobre la secuencia de la tabla)
GRANT INSERT ON tabla1 TO vicerector;
GRANT UPDATE ON tabla1_id_seq TO vicerector;
Una vez accedido al servidor como usuario vicerector usted podr ejecutar sin problemas: INSERT
INTO tabla1 values (1,Juan); pero no podr ver los datos ingresados porque el usuario no tiene
asignado el privilegio SELECT.
Borrando Usuarios
drop user pilar;
Cambiando el propietario de una base de datos
ALTER DATABASE dbname OWNER TO newowner;
El permiso de super usuario es el ms alto, con este usuario se podrn administrar todos los objetos
del motor de base de datos, para asignar este privilegio a un rol lo hacemos con el siguiente
comando:
PL/PgSQL, C, C++, Java PL/Java web, PL/Perl, plPHP, PL/Python, PL/Ruby, PL/sh, PL/Tcl,
PL/Scheme.
El lenguaje de procedimientos PL/pgSQL por ser el que se dispone. PL/pgSQL es muy parecido al
lenguaje PL/SQL utilizado por Oracle que es considerado por muchos, como uno de los mejores
lenguajes de procedimientos que se usar en PostgreSQL, es fcil de aprender, potente y siempre est
disponible.
Fcil de usar
Todas las opciones despus de "LANGUAGE plpgsql" tienen unos valores por defecto que
simplifican mucho la definicin de un procedimiento.
argmodo: El modo de un argumento puede ser IN, OUT, or INOUT. Por defecto se usa IN si no se
define.
argtipo: Los tipos que podemos utilizar son todos los disponibles en PostgreSQL y todos los
definidos por el usuario
IMMUTABLE: Indica que la funcin no puede alterar a la base de datos y que siempre devolver el
mismo resultado, dados los mismos valores como argumentos. Este tipo de funciones no pueden
realizar consultas en la base de datos.
STABLE: Indica que la funcin no puede alterar a la base de datos y que siempre devolver el
mismo resultado en una consulta individual de una tabla, dados los mismos valores como
argumentos. El resultado podra cambiar entre sentencias SQL.
VOLATILE: Indica que la funcin puede devolver diferentes valores, incluso dentro de una consulta
individual de una tabla (valor por defecto)
SECURITY INVOKER: Indica que la funcin se ejecutar con los privilegios del usuario que la
ejecuta (valor por defecto)
SECURITY DEFINER: Indica que la funcin se ejecutar con los privilegios del usuario que la
creo.
El resto de opciones son avanzadas y podr leer sobre ellas en la documentacin oficial de
PostgreSQL.
Vamos a ver unos cuantos ejemplos que nos aclaren un poco cmo definir, instalar y usar un
procedimiento almacenado en PL/pgSQL (estos ejemplos han sido comprobados en postgreSQL.
Lo primero que tenemos que hacer es instalar el lenguaje plpgsql si no lo tenemos instalado.
Si queremos que cualquier usuario con acceso a la base de datos pueda usarlo sin tener que ser el
administrador postgres, tendremos que utilizar TRUSTED con el comando anterior.
A continuacin creamos nuestro primer procedimiento. (Podemos copiar y pegar en el cliente psql,
escribirlo a mano usar el editor interno en psql (\e)):
SENTENCIAS DE CONTROL
SENTENCIA ( IF ... THEN) En PL/SQL solo disponemos de la estructura condicional IF. Su sintaxis
se muestra a continuacin:
IF expression THEN
statements
[ELSE
statements]
END IF
IF (expresion) THEN
-- Instrucciones
ELSIF (expresion) THEN
-- Instrucciones
ELSE
-- Instrucciones
END IF;
expression debe devolver un valor que al menos pueda ser adaptado en un tipo booleano, considere
los siguientes ejemplos:
CREATE OR REPLACE FUNCTION ejemplo_txt(integer, integer) RETURNS text AS $$
DECLARE
numero1 ALIAS FOR $1;
numero2 ALIAS FOR $2;
constante CONSTANT integer := 100;
resultado INTEGER;
resultado_txt TEXT DEFAULT 'El resultado es 104';
BEGIN
resultado := (numero1 * numero2) + constante;
IF resultado <> 104 THEN
resultado_txt := 'El resultado NO es 104';
END IF;
RETURN resultado_txt;
END;
$$ LANGUAGE plpgsql;
Solo queda decir que en la definicin de un procedimiento no solo se tiene en cuenta el nombre del
mismo para diferenciarlo de otros, los argumentos de la funcin tambin se tienen en cuenta:
ejemplo(), ejemplo(integer), ejemplo(integer, integer) y ejemplo(text) son todos procedimientos
diferentes, aunque se llamen igual.
En psql existe un comando muy bueno que nos ensea como una funcin est definida en la base de
datos.
practica=# \x
Expanded display is on.
-[ RECORD 1 ]-------+----------------------------------------------------
Schema | public
Name | ejemplo_txt
Result data type | text
Argument data types | integer, integer
Volatility | volatile
Owner | postgres
Language | plpgsql
Source code |
: DECLARE
: numero1 ALIAS FOR $1;
: numero2 ALIAS FOR $2;
: constante CONSTANT integer := 100;
: resultado INTEGER;
: resultado_txt TEXT DEFAULT 'El resultado es 104';
: BEGIN
: resultado := (numero1 * numero2) + constante;
: IF resultado <> 104 THEN
: resultado_txt := 'El resultado NO es 104';
: END IF;
: RETURN resultado_txt;
: END;
:
Description |
ASIGNACIN
identifier := expression;
Si el tipo de dato resultante de la expresin no coincide con el tipo de dato de las variables, o la
variable tienen un tamao o precisin conocido (como char(29)), el resultado ser amoldado
implcitamente por el intrprete de bytecode de PL/pgSQL, usando los tipos de las variables para las
funciones de entrada y los tipos resultantes en las funciones de salida. Ntese que esto puede
potencialmente producir errores de ejecucin generados por los tipos de las funciones de entrada.
Una asignacin de una seleccin completa en un registro o fila puede hacerse del siguiente modo:
target puede ser un registro, una variable de fila o una lista separada por comas
de variables y campo de registros o filas.
Si una fila o una lista de variables se usan como objetivo, los valores seleccionados han de coincidir
exactamente con la estructura de los objetivos o se producir un error de ejecucin. La palabra clave
FROM puede preceder a cualquier calificador vlido, agrupacin, ordenacin, etc. que pueda pasarse
a una sentencia SELECT.
Existe una variable especial llamada FOUND de tipo booleano, que puede usarse inmediatamente
despus de SELECT INTO para comprobar si una asignacin ha tenido xito.
PERFORM query
Volviendo de la funcin
RETURN expression
Las expresiones resultantes sern amoldadas automticamente en los tipos devueltos por la funcin,
tal como se ha descrito en el caso de las asignaciones.
Dentro del formato, "%" se usa como situacin para los subsecuentes identificadores,
separados por comas. Los posibles niveles son DEBUG (suprimido en las bases de datos
de produccin), NOTICE (escribe en el registro de la base de datos y lo enva a la
aplicacin del cliente) y EXCEPTION (escribe en el registro de la base de datos y aborta
la transaccin).
LOOP
WHILE
FOR
El bucle LOOP, se repite tantas veces como sea necesario hasta que se fuerza su salida con la
instruccin EXIT. Su sintaxis es la siguiente
LOOP
-- Instrucciones
IF (expresion) THEN
-- Instrucciones
EXIT;
END IF;
END LOOP;
Para probarlo:
SELECT ejemplo_loop();
Para ejecutarlo:
SELECT cuenta_caracter('Todo nos es lisito pero no todo nos conviene','o');
El bucle FOR, se repite tanta veces como le indiquemos en los identificadores inicio y final.
FOR contador IN [REVERSE] inicio..final LOOP
-- Instrucciones
END LOOP;
En el caso de especificar REVERSE el bucle se recorre en sentido inverso. Aqu algunos modelos
de cmo utilizar el bucle FOR:
Cuando se desea que una funcin devuelva un grupo de datos debe definirse la misma con la
instruccin SETOF definiendo un tipo de datos. Veamos los siguientes ejemplos:
En la actualidad, una variable de tipo fila slo puede ser declarada usando la notacin %ROWTYPE;
aunque uno podra esperar que un nombre pblico de nombre de tabla funcionada como tipo de
declaracin, sta no sera aceptada dentro de funciones PL/pgSQL.
Los parmetros para una funcin pueden ser tipos compuestos (filas completas de tablas). En ese
caso, el correspondiente identificador $n ser una variable tipo fila, y los campos podrn ser
accedidos, por ejemplo $1.nombrecampo.
Slo los atributos de una tabla definidos por el usuario son accesibles en una variable tipo fila, y no
OID u otros atributos de sistema (porque la fila podra venir de una vista). Los campos del tipo fila
heredan el tamao del campo de la tabla as como la precisin para tipos de datos, tales como
char(n).
ATRIBUTOS
Usando los atributos %TYPE y %ROWTYPE, puede declarar variables con el mismo tipo de datos o
estructura que otro elemento de la base de datos (por ejemplo: un campo de tabla).
variable%TYPE
%TYPE proporciona el tipo de datos de una variable o de una columna de base de datos. Puede usar
esto para declarar variables que almacenen valores de base de datos. Por ejemplo, digamos que tiene
una columna llamada user_id en su tabla usuarios. Para declarar una variable con el mismo tipo de
datos que usuarios.user_id usted escribira:
Id usuarios.user_id%TYPE;
Usando %TYPE no necesita conocer el tipo de datos de la estructura a la que est referenciando, y lo
ms importante, si el tipo de datos del elemento referenciado cambia en el futuro (por ejemplo: usted
cambia su definicin de tabla para user_id de INTEGER a REAL), no necesitar cambiar su
definicin de funcin.
tabla%ROWTYPE
%ROWTYPE proporciona el tipo de datos compuesto correspondiente a toda la fila de la tabla
especificada. La tabla debe ser una tabla existente o un nombre de vista de la base de datos.
DECLARE
users_rec usuarios%ROWTYPE;
user_id usuarios.user_id%TYPE;
BEGIN
user_id := users_rec.user_id;
...
Para agregar datos mediante un procedimiento almacenado en postgres sera de la siguiente forma:
Uno de los puntos ms importantes en un motor de base de datos es proporcionar los mecanismos
adecuados para manejar la concurrencia, es decir, como asegurar la integridad de los datos y la
correctitud de las operaciones realizadas cuando existen mltiples personas intentando acceder a la
misma informacin.
Para ejemplificar el concepto, usemos un ejemplo cotidiano. Los cajeros automticos (Redbanc /
ATM) realizan descuentos del saldo de la cuenta corriente o de ahorro cuando se obtiene dinero de
ellos. Supongamos que en un momento determinado existe un usuario sacando dinero y
simultneamente se esta realizando un cobro electrnico sobre la misma cuenta. El mecanismo
seria: Cuanto dinero hay en la cuenta?; Del saldo descuente esta cantidad de dinero.
Si esta operacin puede ser realizada EXACTAMENTE al mismo tiempo, entonces se obtendr el
resultado de la tabla anterior. As es necesario proveer mecanismos de bloqueo temporal para
asegurar que solo una instancia tenga acceso a los datos concurrentemente (simultneamente).
Una transaccin es una operacin que se realiza por completo, de forma atmica. En caso de fallar
algo, los cambios se revierten y todo vuelve al estado anterior. Postgres sigue el estndar SQL para la
sintaxis de transacciones:
BEGIN WORK;
COMMIT;
Cada transaccin comienza con el comando BEGIN WORK, aunque WORK esopcional. Al
terminar el trabajo se debe invocar al comando COMMIT para indicar que la transaccin ha
concluido. En cualquier punto de la transaccin se puede invocar a ROLLBACK, comando que
deshace todos los cambios realizados en la base de datos, dejndola en el estado previo al inicio de la
transaccin.
BEGIN WORK;
ROLLBACK;
En el caso de que un comando SQL falle, Postgres ignorar las siguientes sentencias hasta el fin de la
transaccin, la cual se indica con COMMIT o ROLLBACK. Las transacciones en Postgres pueden
ser grabadas en un punto intermedio, de manera que pueda re-ejecutar o deshacer solo una porcin de
la transaccin. Para esto se utiliza SAVEPOINT.
BEGIN WORK;
SAVEPOINT s1;
COMMIT;
CURSORES EN POSTGRES
Para el manejo de grandes cantidades de datos tanto en PostgreSQL como en otras bases de datos
relacionales existe el concepto de cursors (cursores) los cuales representan un resultset (conjunto de
datos) que son asociados a una variable, una variable de tipo cursor. Esta variable representa un
apuntador hacia una tabla virtual representada por una consulta y su respectivo comando SELECT
asociado.
La diferencia entre un comando SELECT no asociado a un cursor y uno asociado, es que en el
primero la consulta regresar todos los registros a la vez y si queremos limitar la cantidad de registros
para procesar debemos correr la consulta nuevamente agregando WHERE, BETWEEN o cualquier
otra instruccin para filtrar los resultados. En el caso del comando asociado a un cursor este nos
permite desplazarnos y limitar la cantidad de registros para procesar dentro del resultset sin necesidad
de un nuevo comando SELECT.
Para mostrar la diferencia entre una consulta sin cursor y una consulta asociada a un cursor,
ejecutamos la siguiente consulta.
Esta consulta nos devuelve el resultado acostumbrado y que ya se ha tratado en captulos anteriores
en el presente manual.
-----------------------+------------------------+---------------------+-------------------------------+-----------------
Ahora mostramos los comandos que pueden utilizarse al asociar una consulta a un cursor. Para el
trabajo con cursores es necesario que estos se encuentren dentro del mbito de una TRANSACCIN.
BEGIN;
Declaramos el cursor como una variable de tipo cursor y le asociamos una consulta SQL.
Ahora podemos navegar entre los registros del resultset, con el comando FETCH, de este comando la
sintaxis es:
3. Nos ubicamos sobre el registro que se desea manipular, para el este caso se trata del primero:
Todo el acceso a cursores en PL/pgSQL va a travs de variables cursor, las cuales son siempre del
tipo de datos especial refcursor. Una forma de crear una variable tipo cursor es declararla como de
tipo refcursor. Otra forma es usar la sintaxis de declaracin de cursor, la cual en general es:
(NOTA: FOR puede ser reemplazado por IS para compatibilidad con Oracle)
Los argumentos, si los hay, son pares de tipos de datos name separados por comas que definen
nombres a ser reemplazados por valores de parmetros en la consulta dada. Los actuales valores a
sustituir para estos nombres sern especificados ms tarde, cuando el cursor es abierto.
Algunos ejemplos:
DECLARE
curs1 refcursor;
curs2 CURSOR FOR SELECT * from tenk1;
curs3 CURSOR (key int) IS SELECT * from tenk1 where unique1 = key;
Estas tres variables tienen el tipo de datos refcursor, pero la primera puede ser usada con cualquier
consulta, mientras que la segunda tiene una consulta completamente especificada para trabajar con
ella, y la ltima tiene una consulta parametrizada (key ser reemplazado por un valor de parmetro
entero cuando el cursor es abierto). La variable curs1 ser obviada, ya que no est asignada a ninguna
consulta en particular.
ABRIENDO CURSORES
Antes de que un cursor pueda ser utilizado para retornar filas, ste debe ser abierto (esta es la accin
equivalente al comando SQL DECLARE CURSOR). PL/pgSQL tiene cuatro formas para el
estamento OPEN, dos de las cuales usan variables cursor no asignadas y las otras dos usan variables
cursor asignadas.
OPEN curs2;
OPEN curs3(42);
Usando Cursores
Una vez un cursor ha sido abierto, ste puede ser manipulado con los estamentos descritos aqu.
Estas manipulaciones no necesitan ocurrir en la misma funcin que abri el cursor. Puede retornar un
valor refcursor de una funcin y permitir al peticionario operar con el cursor (internamente, un valor
refcursor es simplemente la cadena nombre de una Portal conteniendo la consulta activa para el
cursor. Este nombre puede ser pasado, asignado a otras variables refcursor, sin afectar al Portal).
Todos los Portales son implcitamente cerrados al final de la transaccin. Por tanto un valor refcursor
es til para referenciar un cursor abierto slo hasta el final de la transaccin.
FETCH
FETCH cursor INTO target;
FETCH retorna la siguiente fila desde el cursor a un destino, el cual puede ser una variable fila,
registro o una lista de vairbales simples, separadas por comas, tal como en un SELECT INTO. Al
igual que en un SELECT INTO, la variable especial FOUND puede ser chequeada para ver si se
obutvo o no una fila.
CLOSE
CLOSE cursor;
CLOSE cierra el Portal de un cursor abierto. Esto puede ser suado para liberar recursos antes del final
de una transaccin, o para liberar la variable cursor para abrirla de nuevop.
CLOSE curs1;
Retornando Cursores
Las funciones PL/pgSQL pueden retornar cursores al peticionario. Esto es usado para retornar
mltiples filas o columnas desde la funcin. La funcin abre el cursor y retorna el nombre del cursor
al peticionario. El peticionario entonces puede obtener (con FETCH) filas desde el cursor. El cursor
puede ser cerrado por el remitente, o ser cerrado automticamente cuando termine la transaccin.
El nombre del cursor retornado por la funcin puede ser especificado por el peticionario o generado
automticamente. El siguiente ejemplo muestra cmo un nombre de cursor puede ser proporcionado
por el peticionario:
BEGIN;
SELECT periodos('listaperiodos');
FETCH ALL IN listaperiodos;
COMMIT;
El siguiente ejemplo utiliza una vista como referencia para ser utilizada en el cursor:
CREATE OR REPLACE VIEW V_Lista_Profesores AS
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, Titulacion
FROM profesores, personas
WHERE profesores.IdPersona = personas.IdPersona AND profesores.cargo Like 'Prof%'
ORDER BY ApellidoPaterno;
BEGIN;
SELECT profes('listaprofes');
FETCH 2 FROM listaprofes;
FETCH 5 FROM listaprofes;
FETCH BACKWARD 3 FROM listaprofes;
FETCH ALL IN listaprofes;
COMMIT;
El siguiente ejemplo usa el cursor de forma referencial, para poder utilizarlo usted debe tomar el
nombre que le da como referencia <unnamed portal 1> que le da como resultado al ejecutar la funcin:
BEGIN;
SELECT listado();
listado
--------------------
<unnamed portal 1>
(1 fila)
Ejemplo utilizando una funcin estandar para devover datos desde 2 tablas:
CREATE OR REPLACE FUNCTION curso_paralelo(refcursor, refcursor) RETURNS SETOF
refcursor AS $$
BEGIN
OPEN $1 FOR SELECT * FROM Cursos;
RETURN NEXT $1;
OPEN $2 FOR SELECT * FROM paralelos;
RETURN NEXT $2;
END;
$$ LANGUAGE plpgsql;
BEGIN;
SELECT * FROM curso_paralelo('a', 'b');
FETCH ALL FROM a;
FETCH ALL FROM b;
COMMIT;
Se podra realizar un ejemplo utilizando una funcin que aplique filtrados mediante un argumento:
CREATE OR REPLACE FUNCTION personasxiniciales(refcursor,text) RETURNS refcursor
AS $$
BEGIN
OPEN $1 FOR SELECT * FROM personas WHERE apellidopaterno LIKE $2 || '%';
RETURN $1;
END; $$ LANGUAGE 'plpgsql' VOLATILE;
BEGIN;
SELECT personasxiniciales('lista','M');
FETCH ALL IN lista;
COMMIT;
TRIGGERS (Disparadores)
Un trigger es una accin que se lanza cuando se inserta, elimina o actualiza una o varios registros de
una tabla. En PL/pgSQL, los triggers son funciones sin argumentos en las cuales se crean las
siguientes variables:
NEW: Es un Record con los datos del registro que se est insertando (actualizando).
TG_OP: Operacin que se est realizando, puede ser INSERT, UPDATE, DELETE, o
TRUNCATE.
Para desarrollar un trigger se tienes que hacer dos cosas: Crear una funcion para el trigger y despus
instalar el trigger en una/varias tablas.
Para probar el funcionamiento de un trigger crearemos una tabla con las siguientes caractersticas:
cuadrado bigint,
cubo bigint,
raiz2 real,
raiz3 real,
);
Una vez creada la tabla crearemos una funcin que llenar los datos calculado, esto se activar al
momento ingresar un nmero a la tabla NUMEROS:
DECLARE
BEGIN
NEW.cuadrado := power(NEW.numero,2);
NEW.cubo := power(NEW.numero,3);
NEW.raiz2 := sqrt(NEW.numero);
NEW.raiz3 := cbrt(NEW.numero);
RETURN NEW;
Cuando ya se tiene la tabla y la funcin, procedemos a crear un trigger que se activar antes de
insertar o actualizar un registro de la tabla:
Ahora para probar su funcionamiento solo basta con insertar un registro a la tabla:
Que pasara si necesitamos proteger los registros y evitar la eliminacin, para lograrlo tendramos que
realizar esto:
RETURN NULL;
sta funcin retornar cancelacin cada vez que sea ejecutada, por lo que se aplicara a un trigger
acorde a la necesidad, por ejemplo:
Para probar su funcionamiento ejecutamos la siguiente orden de eliminacin y notar que no se podr
eliminar registros en sta tabla:
Aplicando ejemplos con la base de datos UNIDAD, crearemos una funcin que valida el ingreso de
datos sobre la tabla PERSONAS:
BEGIN
IF LENGTH(TRIM(NEW.apellidoPaterno))>0 THEN
NEW.ApellidoPaterno= UPPER(NEW.ApellidoPaterno);
ELSE
NEW.ApellidoPaterno=No Registrado;
END IF;
IF LENGTH(TRIM(NEW.apellidoMaterno))>0 THEN
NEW.ApellidoMaterno= UPPER(NEW.ApellidoMaterno);
ELSE
NEW.ApellidoMaterno=No Registrado;
END IF;
IF LENGTH(TRIM(NEW.Nombres))>0 THEN
NEW.Nombres= UPPER(NEW.Nombres);
ELSE
NEW.Nombres=No Registrado;
END IF;
IF LENGTH(TRIM(NEW.Direccion))>0 THEN
NEW.Direccion= UPPER(NEW.Direccion);
ELSE
NEW.Direccion=No Registrado;
END IF;
IF LENGTH(TRIM(NEW.Telefono))=0 THEN
NEW.Telefono=No Registrado;
END IF;
NEW.sexo=M;
END IF;
NEW.EstadoCivil='S';
END IF;
RETURN NEW;
Una caracterstica especial que se le puede aplicar a una base de datos, es la de registrar las
responsabilidades sobre quin agreg, actualiz o elimin datos en una o varias tablas de la base de
datos, a este control se le denomina auditora de registros, para lograrlo se crear una tabla que
registre los movimientos de gestin que los usuarios realizan sobre la base de datos, la tabla podra
quedar de la siguiente forma:
Fecha timestamp,
Usuario varchar(40),
Proceso varchar(20),
);
La funcin AUDITORIA utiliza una variable especial para trabajar con trigger con el nombre TG_OP,
esta permite reconocer la accin que se esta ejecutando, la funcin utiliza esta cualidad para definir
que datos se registran en la tabla AudtoriaUsuario cuando se eliminan datos, actualizan o se
agregan nuevos registros:
DECLARE
contenido Varchar(255);
BEGIN
IF (TG_OP = 'DELETE') THEN
contenido:= OLD.IdPersona || ' ' || OLD.ApellidoPaterno || ' ' || OLD.ApellidoMaterno || ' ' ||
OLD.Nombres;
RETURN OLD;
RETURN NEW;
RETURN NEW;
END IF;
Definida la funcin creamos el trigger para que se active la funcin AUDITORIA despus de insertar
nuevos registros, actualizar o eliminar datos sobre la tabla Personas.
NEW
Tipo de dato RECORD; Variable que contiene la nueva fila de la tabla para las operaciones
INSERT/UPDATE en disparadores del tipo row-level. Esta variable es NULL en disparadores del
tipo statement-level.
OLD
Tipo de dato RECORD; Variable que contiene la antigua fila de la tabla para las operaciones
UPDATE/DELETE en disparadores del tipo row-level. Esta variable es NULL en disparadores del
tipo statement-level.
TG_NAME
Tipo de dato name; variable que contiene el nombre del disparador que est usando la funcin
actualmente.
TG_WHEN
Tipo de dato text; una cadena de texto con el valor BEFORE o AFTER dependiendo de como el
disparador que est usando la funcin actualmente ha sido definido
TG_LEVEL
Tipo de dato text; una cadena de texto con el valor ROW o STATEMENT dependiendo de como el
disparador que est usando la funcin actualmente ha sido definido
TG_OP
Tipo de dato text; una cadena de texto con el valor INSERT, UPDATE o DELETE dependiendo de la
operacin que ha activado el disparador que est usando la funcin actualmente.
TG_RELID
Tipo de dato oid; el identificador de objeto de la tabla que ha activado el disparador que est usando
la funcin actualmente.
TG_RELNAME
Tipo de dato name; el nombre de la tabla que ha activado el disparador que est usando la funcin
actualmente. Esta variable es obsoleta y puede desaparacer en el futuro. Usar TG_TABLE_NAME.
TG_TABLE_NAME
Tipo de dato name; el nombre de la tabla que ha activado el disparador que est usando la funcin
actualmente.
TG_TABLE_SCHEMA
Tipo de dato name; el nombre de la schema de la tabla que ha activado el disparador que est usando
la funcin actualmente.
TG_NARGS
Tipo de dato integer; el nmero de argumentos dados al procedimiento en la sentencia CREATE
TRIGGER.
TG_ARGV[]
Tipo de dato text array; los argumentos de la sentencia CREATE TRIGGER. El ndice empieza a
contar desde 0. Indices invlidos (menores que 0 mayores/iguales que tg_nargs) resultan en valores
nulos.