Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Introduccion A PostgreSQL
Introduccion A PostgreSQL
Introduccin a PostgreSQL
Qu es PostgreSQL?
PostgreSQL es un sistema manejador de bases de datos relacionales basado en postgres 4.2, desarrollado en el departamento Berkeley de Ciencias de la computacin en la universidad de California. Postgres es Open Source descendiente del cdigo original Berkeley, soporta el estndar SQL y ofrece otros recursos tales como:
complex queries foreign keys Triggers Views transactional integrity multiversion concurrency control index methods procedural languages
Postgres puede ser usado, modificado o distribuido para uso privado, comercial o Acadmico
Introduccin a PostgreSQL
Ahora probaremos un poco la terminal interactiva llamada psql: para probarla teclee las siguientes consultas:
SELECT version();
SELECT current_date; SELECT 2 + 2;
Introduccin a PostgreSQL
Ahora crearemos una tabla llamada climas, este ejemplo nos servir para verificar su estructura: CREATE TABLE climas ( ciudad varchar(80), temp_baja int, -- baja temperatura temp_alta int, -- alta temperatura prcp real, -- precipitacion fecha date );
Ahora crearemos otra tabla llamada ciudades, una de las cualidades de esta es que utilizara un tipo de dato especifico de postgres, el tipo POINT.
CREATE TABLE ciudades ( nombre varchar(80), localizacion point );
Nota: Si desea eliminar una tabla utilice el siguiente comando: DROP TABLE tablename;
Ya creadas nuestras tablas ahora procederemos a utilizar INSERT el Statement (Sentencia) que nos servir para insertar datos en nuestras tablas, su sintaxis puede ser alguna de las siguientes:
INSERT INTO climas ( ciudad, temp_baja , temp_alta, prcp, fecha) VALUES ('Mexico', 5, 30, 0.25, '2009-06-23'); INSERT INTO climas VALUES ('Atlautla', 5, 30, 0.25, '2009-06-23');
Como se menciono anteriormente postgres soporta el estndar SQL as que para realizar una consulta, puede utilizar el SELECT con sus respectivas clusulas FROM, WHERE y los operadores. Por ejemplo: --Esto nos Arrojara una tabla con todos los registros SELECT * FROM climas; --Esto nos una tabla con los campos especificados SELECT Ciudad, temp_baja,temp_alta FROM climas; --Esto nos mostrar solo la ciudad llamado Atlautla solo si su prcp(precipitacin) es mayor a 20 SELECT * FROM climas WHERE Ciudad = 'Atlautla' AND prcp > 0.20;
--Muestra todos los registros ordenados por el nombre de la ciudad SELECT * FROM climas ORDER BY ciudad;
AND Y lgica o Conjuncin OR O lgica o Disyuncin = Igual a >= Mayor o Igual <= Menor o Igual <> o != Diferente
Muchas veces necesitamos acceder a mas de una tabla al mismo tiempo, para ello utilizares los joins que nos permitirn acceder a mltiples registros de dos o mas tablas al mismo tiempo. Un JOIN es la unin de dos o mas tablas. Por ejemplo:
SELECT * FROM climas, ciudades WHERE ciudad=
'Mexico';
SELECT climas.ciudad, climas.temp_baja,
climas.temp_alta, climas.prcp, climas.fecha, ciudades.localizacion FROM climas, ciudades WHERE ciudades.nombre = climas.ciudad;
Las funciones de agregacin realizan operaciones con un conjunto de valores. Por ejemplo:
Encontrar promedios o encontrar el mximo o mnimo valor.
SELECT max(temp_baja) FROM climas; SELECT ciudad FROM climas WHERE temp_baja
climas WHERE ciudad LIKE 'M% GROUP BY ciudad HAVING max(temp_baja) < 40;
Esta sentencia se utiliza para actualizar algunos datos o cuando estos han cambiado o simplemente por algn error en la insercin Por ejemplo:
SELECT * FROM climas;
La sentencia Delete se utiliza para eliminar registros de las tablas, Por ejemplo:
DELETE FROM climas WHERE
ciudad='Mexico';
Su sintaxis es:
DELETE FROM NombreTabla
(Condicion);
Este es un concepto bsico de las base de datos orientados a objetos, por ejemplo considere dos tablas:
CREATE TABLE ciudad ( nombre text, poblacion real, altitud int -- (in ft) );
CREATE TABLE capital ( estado char(2) ) INHERITS (ciudad);
Una llave fornea es una referencia entre tablas (campo coincidente), si ahora agregamos llaves forneas a nuestras tablas de ejemplo, su estructura quedara de la siguiente manera: CREATE TABLE ciudades ( ciudad varchar(80) primary key, localizacion point );
CREATE TABLE climas ( ciudad varchar(80) references ciudades(ciudad), temp_baja int, temp_alta int, prcp real, fecha date);
Para crear las PKs y FKs a tablas ya existentes, usamos la siguiente sentencia:
CREATE TABLE ciudades ( ciudad varchar(80) primary key, localizacion point );
ciudad_pk
MATCH tipo ON DELETE accion ON UPDATE accion En donde tipo puede tener estos valores:
FULL: No permite que una columna tenga el valor NULL en una clave fornea compuesta por varias columnas SIMPLE: Permite que una columna tenga el valor NULL en una clave fornea compuesta por varias columnas
NO ACTION: Produce un error indicando que un DELETE UPDATE crear una violacin de la clave fornea definida.
RESTRICT: Produce un error indicando que un DELETE UPDATE crear una violacin de la clave fornea definida.
CASCADE: Borra actualiza automticamente todas las referencias activas SET NULL: Define las referencias activas como NULL SET DEFAULT: Define las referencias activas como el valor por defecto (si est definido) de las mismas
Ahora si tratramos de hacer una insercin en la tabla climas postgres lanzar un error indicando que ese campo no existe en la tabla ciudades, por tanto nuestros datos quedaran ntegros y no abra informacin dems.
NOTA: Un campo para poder ser llave fornea deber ser del mismo tipo de dato de la otra tabla.
Una vista es una tabla virtual que puede contener campos de una o varias tablas, y estas a su vez se manipulan como tablas, cualquier Statement SELECT puede ser una vista. Para crear una vista:
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW name [ ( column_name [, ...] ) ] AS query
CREATE VIEW MiVista AS SELECT temp_baja, temp_alta, prcp, fecha, localizacion FROM climas, ciudades WHERE ciudad = nombre;
Nos permiten ejecutar mltiples consultas y hacer que todas se ejecuten o que ninguna lo haga.
Iniciamos la transaccin con el comando BEGIN, despus ejecutamos alguna sentencia, y para terminar con la transaccin usamos ROLLBACK. Por lo tanto, los datos quedaran intactos al hacer ROLLBACK, lo que deshace todas las operaciones que escribimos.
Estos lenguajes deben ser instalados en la base de datos previamente antes de ser utilizados.
Sin embargo, tambin existe un lenguaje propio de PostgreSQL, denominado "PL/pgsql", que posee estructuras de control y permite aprovechar toda la potencia de SQL para crear nuestras propias funciones.
Se pueden crear funciones para ser ejecutadas en algn evento de la base de datos. Al borrar, modificar o insertar datos por ejemplo. Se pueden aadir estructuras de control al lenguaje SQL, podemos ahora definir ciclos de ejecucin como FOR y WHILE que nos permitan recorrer variables de tipo array, tablas u otras estructuras. Las funciones nos permiten realizar clculos complejos, as ampliamos las funciones pre-definidas por el motor de base de datos y construir funciones a medida de nuestras necesidades o las del cliente/empresa.
Nos aporta una ejecucin fiable para el servidor, es decir, podemos estar seguros del conjunto de instrucciones de la funcin definida se ejecutar, sin importar si ocurren problemas en el cliente, en una conexin o enlace, una vez solicitada la funcin esta se ejecuta en modo seguro y protegido en el servidor.
Es un lenguaje fcil de usar, pues extiende de una manera simplista pero a la vez potente el lenguaje SQL.
El lenguaje PL/pgSQL no es sensible a las maysculas. Todas las palabras clave e identificadores pueden usarse en cualquier mezcla de maysculas y minsculas, sin embargo, de preferencia, el nombre de tablas y de registros utilice segn defini en la base de datos.
PL/pgSQL es un lenguaje orientado a bloques. la estructura bsica del lenguaje se define de la siguiente manera :
CREATE [OR REPLACE] FUNCTION <nombre_de_funcion> ([lista de parmetros]) RETURNS <tipo_de_retorno> AS ' DECLARE <declaracin de variables locales de la funcin> BEGIN <sentencias propias de la funcin> END; ' LANGUAGE 'plpgsql'; NOTA: En algunos casos no se instala el lenguaje 'plpgsql, para instalarlo, solo ejecutamos: CREATE LANGUAGE 'plpgsql';
Una de las caractersticas de PL/pgSQL es que no es necesario definir los nombres de variables en la funcin, slo es necesario definir si tipo, de esta manera tenemos que una funcin puede ser definida en trminos de parmetros de entrada y salida de la siguiente forma :
FUNCTION suma ( real , real ) RETURNS real AS ' ...resto de la funcin... Cabe notar que podemos utilizar como parmetros todos los tipos usados por PostgreSQL, es decir : INTEGER, DATE, TIME, VARCHAR, CHAR, TIMESTAMP, REAL, TEXT y muchos otros, e inclusive tipos definidos por el usuario por medio de la instruccin CREATE TYPE.
Como explicamos anteriormente, las variables locales son definidas dentro de la seccin DECLARE de la funcin, de forma muy similar a otros lenguajes podemos definir variables, por ejemplo :
DECLARE contador integer = 0; cadena varchar; hoy date; bandera bool; suma real;
FUNCTION suma ( real , real ) RETURNS real AS ' DECLARE numero_1 alias for $1; numero_2 alias for $2; valor_total real; ...resto de la funcion... Podemos no definir los alias y usar los parmetros directamente, por ejemplo : valor_total := $1 + $2;
Una vez definidos los parmetros de entrada/salida, y tambin nuestras variables locales, podemos comenzar a trabajar en nuestra funcin en la seccin BEGIN .... END; Las asignaciones de valores se realizan de la misma forma que en PASCAL, es decir, utilizando := como operador de asignacin y punto y coma al final de la lnea, ejemplo :
FUNCTION suma ( real , real ) RETURNS real AS ' DECLARE numero_1 alias for $1; numero_2 alias for $2; valor_total real; BEGIN valor_total := numero_1 + numero_2; numero_1 := numero_1 * numero_2; ...resto de la funcion...
Podemos utilizar sentencias de control para escribir nuestros programas y permitir que sigan un algoritmo no lineal, para ello, contamos bsicamente con las siguientes estructuras : LOOP EXIT IF, ELSE FOR WHILE
Esta sentencia nos permite efectuar un ciclo, su estructura bsica es : ...resto de la funcin... LOOP ...sentencias a ejecutar en el ciclo... END LOOP ...resto de la funcin...
Cuando usamos un ciclo LOOP, es necesario darle una salida para que este mismo termine, la sentencia EXIT nos permite finalizar el LOOP y continuar en la sentencia siguiente a la salida de ste, generalmente, EXIT est acompaado con la sentencia IF, por ejemplo
LOOP ...resto de la funcin... contador := contador + 1; IF contador >= 10 THEN EXIT; -- salida del loop cuando sea mayor o igual que 10 END IF; END LOOP ...resto de la funcin...
Podemos efectuar operaciones de comparacin con las sentencias IF, ELSE, los operadores de comparacin son los siguientes : < menor que ... > mayor que ... <> distinto a ... <= menor o igual que ... >= mayor o igual que ... = igual que ... OR o ... AND y ...
Existen dos tipos de ciclos FOR, el primero tiene que ver claramente con los ciclos numricos comunes, es decir, lo que comnmente se usa para efectuar repeticiones, y por otra parte, tenemos un ciclo FOR que nos permite recorrer tablas y procesar sus datos, esta segunda est ligada a sentencias SQL, veamos entonces como se utiliza la sentencia FOR CASO 1 : SENTENCIA FOR DE PROCESO CICLICO NUMERICO FOR <variable> IN <inicio>..<fin> LOOP ... SENTENCIAS A EJECUTAR DENTRO DEL CICLO FOR ... END LOOP; o bien puede usar el FOR de forma inversa FOR <variable> REVERSE <fin>..<inicio> LOOP ... SENTENCIAS A EJECUTAR DENTRO DEL CICLO FOR ...
CASO 1 : SENTENCIA FOR DE PROCESO CICLICO NUMERICO Ejemplo : ...resto de la funcin... FOR inc IN 1..10 LOOP factorial := factorial * inc; END LOOP; RETURN factorial; ...resto de la funcin
CASO 2: SENTENCIA FOR APLICADA A PROCESOS DE REGISTROS SQL FOR <registro o fila> IN <sentencia SELECT SQL> LOOP ... SENTENCIAS A EJECUTAR DENTRO DEL CICLO FOR ... END LOOP;
Note que para utilizar esta sentencia FOR debemos declarar una variable de tipo RECORD o registro. RECORD es una palabra reservada para estos casos, y no posee una estructura definida pues no ha sido asignada a ninguna tabla, este tipo de dato nos permite recorrer la tabla de productos y obtener sus valores por medio de esta variable.
La sentencia WHILE se ejecuta de forma muy similar a otros lenguajes de programacin, su estructura es la siguiente : WHILE <condicin> LOOP ... SENTENCIAS A EJECUTAR DENTRO DEL CICLO WHILE ... END LOOP;
CREATE OR REPLACE FUNCTION buscar_ciudad (varchar) RETURNS bool AS ' DECLARE rut_buscar alias for $1; registro ciudades%ROWTYPE; /* Ntese que aqu definimos la variable registro del tipo FILA de ciudades indicando la tabla, el smbolo % y luego la palabra reservada ROWTYPE */ BEGIN SELECT INTO registro * FROM ciudades WHERE ciudad = rut_buscar; IF FOUND THEN RETURN true; END IF; RETURN false; END; ' LANGUAGE 'plpgsql'; Como podemos apreciar, este cdigo busca un cliente en la tabla de clientes, si existe o se encuentra el cliente, la funcin devolver un valor verdadero (true), de lo contrario, sta devolver falso (false)
Ejemplo 2 : Buscar un producto y actualiza su precio segn porcentaje CREATE OR REPLACE FUNCTION actualizar_producto (varchar, real) RETURNS bool AS ' DECLARE producto ALIAS FOR $1; porcentaje ALIAS FOR $2; registro productos%ROWTYPE; BEGIN SELECT INTO registro * FROM productos WHERE id_producto = producto; IF FOUND THEN UPDATE productos SET precio_venta = precio_venta + (precio_venta * porcentaje) WHERE id_categoria = categoria; RETURN true; END IF; RETURN false; END; ' LANGUAGE 'plpgsql; Este cdigo busca el producto, obtiene los datos necesarios y actualiza el registro.
Esta funcin no actualiza realmente los datos de la tabla, solamente procesa los parmetros, de tal manera que si los datos ingresados fueran los de una tabla devolvera el valor mas IVA.
Hasta ahora hemos descrito a grandes rasgos como construir fcilmente funciones de usuario o procedimientos almacenados, pero todava no los hemos invocado, a continuacin ejemplos de llamadas a los procedimientos almacenados o funciones en PL/pgSQL : Este ejemplo retornar true si la ciudad existe o false si no se encuentra en la tabla de clientes (nota, no hay que indicar en que tabla pues eso esta descrito en la funcin). SELECT buscar_ciudad('Mexico');
Es una accin definida en una tabla de nuestra base de datos y ejecutada automticamente por una funcin programada por nosotros. Esta accin se activar, segn la definamos, cuando realicemos un INSERT, un UPDATE un DELETE en la susodicha tabla.
Esta es la definicin del comando SQL que se puede utilizar para definir un disparador en una tabla. CREATE TRIGGER nombre { BEFORE | AFTER } { INSERT | UPDATE | DELETE [ OR ... ] } ON tabla [ FOR [ EACH ] { ROW | STATEMENT }] EXECUTE PROCEDURE nombre de funcin ( argumentos )
Creamos una base de datos para utilizarla con nuestros ejemplos. CREATE TABLE numeros( numero bigint NOT NULL, cuadrado bigint, cubo bigint, raiz2 real, raiz3 real, PRIMARY KEY (numero) );
Despus tenemos que crear una funcin en PL/pgSQL para ser usada por nuestro disparador. Nuestra primera funcin es la ms simple que se puede definir y lo nico que har ser devolver el valor NULL: CREATE OR REPLACE FUNCTION proteger_datos() RETURNS TRIGGER AS $proteger_datos$ DECLARE BEGIN -- Esta funcin es usada para proteger datos en una tabla -- No se permitir el borrado de filas si la usamos -- en un disparador de tipo BEFORE / row-level RETURN NULL; END; $proteger_datos$ LANGUAGE plpgsql;
A continuacin definimos en la tabla numeros un disparador del tipo BEFORE / row-level para la operacin DELETE.
CREATE TRIGGER proteger_datos BEFORE DELETE ON numeros FOR EACH ROW EXECUTE PROCEDURE proteger_datos();
Ahora vamos a definir una nueva funcin un poco ms complicada y un nuevo disparador en nuestra tabla numeros: CREATE OR REPLACE FUNCTION rellenar_datos() RETURNS TRIGGER AS $rellenar_datos$ 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; END; $rellenar_datos$ LANGUAGE plpgsql; CREATE TRIGGER rellenar_datos BEFORE INSERT OR UPDATE ON numeros FOR EACH ROW EXECUTE PROCEDURE rellenar_datos();
Ahora vamos a ver como los disparadores que hemos definido en la tabla numeros funcionan:
El valor de la variable NEW al empezar a ejecutarse rellenar_datos() es numero=2, cuadrado=NULL, cubo=NULL, raiz2=NULL, raiz3=NULL. Nuestra tabla todava no contiene ninguna fila. A continuacin calculamos el cuadrado, el cubo, la raz cuadrada y la raz cbica de 2 y asignamos estos valores a NEW.cuadrado, NEW.cubo, NEW.raiz2 y NEW.raiz3.
El valor de la variable NEW antes de la sentencia RETURN NEW es ahora numero=2, cuadrado=4, cubo=8, raiz2=1.41421, raiz3=1.25992.
Con la sentencia RETURN NEW, retornamos la fila (RECORD) almacenada en la variable NEW, y salimos de la funcin rellenar_datos(). El sistema almacena entonces el RECORD contenido en NEW en la tabla numeros
De la misma manera funciona el disparador proteger_datos cuando ejecutamos una sentencia DELETE. Antes de borrar nada ejecutar la funcin proteger_datos(). Esta funcin retorna el valor NULL y esto significa, segn la regla que hemos definido, que para la fila afectada no se ejecutar el comando DELETE. Por eso y mientras este disparador este instalado ser imposible de borrar nada de la tabla numeros.
Ahora vamos a ver como los disparadores que hemos definido en la tabla numeros funcionan:
Hemos realizado 2 INSERT y 1 UPDATE. Esto significa que por cada uno de estos comandos el sistema ha ejecutado la funcin rellenar_datos(), una vez por cada fila afectada y antes de actualizar la tabla numeros.
Como podemos comprobar, nosotros solamente hemos actualizado la columna numero, pero al listar el contenido de nuestra tabla vemos como el resto de columnas (cuadrado, cubo, raiz2 y raiz3) tambin contienen valores. De esta actualizacin se ha encargado rellenar_datos() llamada por nuestro disparador. la funcin
CASCADE
Elimina automticamente el borrado de objetos que dependen del trigger. RESTRICT Se niegan a eliminar el trigger si los objetos dependen de l. Este es el predeterminado. DROP TRIGGER proteger_datos ON numeros; DROP TRIGGER rellenar_datos ON numeros;
A continuacin crearemos un disparador nico para las sentencias INSERT, UPDATE y DELETE. Para ello utilizaremos la variable TG_OP. CREATE OR REPLACE FUNCTION proteger_y_rellenar_datos() RETURNS TRIGGER AS $proteger_y_rellenar_datos$ DECLARE BEGIN IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE' ) THEN NEW.cuadrado := power(NEW.numero,2); NEW.cubo := power(NEW.numero,3); NEW.raiz2 := sqrt(NEW.numero); NEW.raiz3 := cbrt(NEW.numero); RETURN NEW; ELSEIF (TG_OP = 'DELETE') THEN RETURN NULL; END IF; END; $proteger_y_rellenar_datos$ LANGUAGE plpgsql;
CREATE TRIGGER proteger_y_rellenar_datos BEFORE INSERT OR UPDATE OR DELETE ON numeros FOR EACH ROW EXECUTE PROCEDURE proteger_y_rellenar_datos();
Ahora, todo seguir funcionando de la misma manera que con los dos disparadores del comienzo: INSERT INTO numeros (numero) VALUES (5); INSERT INTO numeros (numero) VALUES (6);
Ahora vamos a definir un disparador del tipo statement-level que se ejecute despus de nuestras sentencias INSERT, UPDATE y DELETE. La funcin ejecutada por este disparador grabar datos de la ejecucin en la tabla cambios. Para demostrar cmo podemos utilizar esto vamos a definir una nueva tabla: CREATE TABLE cambios( timestamp_ TIMESTAMP WITH TIME ZONE default NOW(), nombre_disparador text, tipo_disparador text, nivel_disparador text, comando text );
CREATE OR REPLACE FUNCTION grabar_operaciones() RETURNS TRIGGER AS $grabar_operaciones$ DECLARE BEGIN INSERT INTO cambios ( nombre_disparador, tipo_disparador, nivel_disparador, comando) VALUES ( TG_NAME, TG_WHEN, TG_LEVEL, TG_OP ); RETURN NULL; END; $grabar_operaciones$ LANGUAGE plpgsql;
CREATE TRIGGER grabar_operaciones AFTER INSERT OR UPDATE OR DELETE ON numeros FOR EACH STATEMENT EXECUTE PROCEDURE grabar_operaciones();