Вы находитесь на странице: 1из 5

P r c t i c a 28

Funciones

Objetivo
En esta prctica se analizan los diferentes tipos de funciones que se pueden programar en PostgreSQL, as como la
forma de crear un sistema de reglas.

Introduccin
El SMBD Postgres SQL proporciona tres tipos de funciones:
Funciones de lenguaje de consultas (funciones escritas en SQL)
Funciones de lenguaje procedural (funciones escritas en lenguaje PLSQL)
Funciones de lenguaje de programacin (funciones escritas en un lenguaje de programacin
compilado como C)
Una forma sencilla de proteger la informacin contenida en una tabla, ante la posibilidad de que alguien
pueda insertar, actualizar o eliminar datos de manera indebida es mediante la definicin de reglas.
El sistema de reglas se sita entre el traductor de la consulta y el optimizador. Toma la salida del
traductor, un rbol de la consulta, y las reglas de reescritura contenidas en el catlogo pg_rewrite, y crea
cero o muchos rboles de consulta como resultado.

Un rbol de consulta es una representacin interna de una instruccin SQL donde se almacenan por
separado las partes menores que la componen. Estos rboles son visibles cuando arrancamos el motor
de Postgres con nivel de debug 4 y tecleamos consultas en la interface interactiva, pero leer un rbol de
consultas requiere experiencia y es bastante difcil al principio.

Correlacin con el programa


Tema 6. SQL Procedural.
Subtema 6.1. Procedimientos almacenados.

Equipo necesario
Una computadora con sistema operativo Windows 7 o superior que cuente con el Shell de PostgreSQL
conocido como psql.

Metodologa
1. Oprima el botn de Inicio de Windows y localice PostgreSQL 9.6 en la lista de todos los programas
y ah encontrar el acceso directo para ejecutar la herramienta SQL Shell (psql).
1. Se abre la ventana del shell de PostgreSQL, primero le solicita indicar el servidor, oprima enter.
2. Ahora le solicita indicar la base de datos, ah va a escribir la base de datos banco y oprima enter.
Taller de Bases de Datos Prctica 28

3. Con el puerto y el usuario, oprima enter en ambos casos.


4. Finamente le solicita la contrasea, recuerde cul defin en la primera prctica, oprima enter.
5. Para ilustrar una funcin SQL sencilla, va a crear una para depositar en una cuenta bancaria, en
este caso los argumentos son el nmero de cuenta y el monto del depsito y se denotan como $1 y
$2 respectivamente (observe el uso del doble apstrofo):
banco=# CREATE FUNCTION deposito (integer, double precision)
banco-# RETURNS text
banco-# AS 'UPDATE cuentas SET saldo = saldo + $2 WHERE numero = $1;
banco'# SELECT CASE WHEN count(*)=1 THEN ''depsito realizado con xito''
banco'# ELSE ''depsito no realizado'' END AS resultado from cuentas
banco'# WHERE numero=$1'
banco-# language 'sql';

6. Genere una imagen que evicencie la creacin de esta funcin.


7. Ahora puede ejecutar esta funcin para abonar $100.00 en la cuenta 6993 de la siguiente forma:
banco=# SELECT * FROM cuentas;
banco=# SELECT deposito(6993,100.0);
banco=# SELECT * FROM cuentas;

8. Y pruebe tambin que sucede en caso de indicar una cuenta inexistente:


banco=# SELECT deposito(6990,100.0);

9. Genere una imagen que evidencie la realizacin del depsito.


10. Ahora cambie de base de datos:
banco=# \c Biblioteca;

11. En este otro ejemplo se toma un argumento sencillo de tipo texto que corresponde al nombre del
editorial y devuelve un resultado de un tipo direc que fue definido por el usuario:
Biblioteca=# CREATE FUNCTION dir(text)
Biblioteca-# RETURNS direc
Biblioteca-# AS 'SELECT "Direccion" FROM "Editoriales" WHERE "Nombre"=$1'
Biblioteca-# language 'sql';

12. Para probar su funcin ejecute lo siguiente:


Biblioteca-# SELECT dir('Marcombo');

13. Genere una imagen que evidencie la realizacin de la consulta.


14. Ahora va a construir una funcin que calcule la edad de una persona:
Biblioteca=# CREATE FUNCTION edad(fecha1 DATE, fecha2 DATE)
Biblioteca-# RETURNS DOUBLE PRECISION
Biblioteca-# AS 'SELECT (extract(year from fecha2)-extract(year from
Biblioteca'# fecha1))- CASE WHEN (extract(DOY from fecha2)<extract(DOY
Biblioteca'# from fecha1)) THEN 1 ELSE 0 END'
Biblioteca-# language 'sql';

15. Genere una imagen que evicencie la creacin de esta funcin.


16. Despus de haber desarrollado la funcin anterior, podr usarla de la siguiente manera, suponiendo
que Pedro naci el 25/dic/1992, ahora su edad es de:
Biblioteca=# SELECT edad('1992-12-25', CURRENT_DATE);

17. Es equivalente si escribe la fecha en el formato habitual:


Taller de Bases de Datos Prctica 28

Biblioteca=# SELECT edad('25/12/1992', CURRENT_DATE);

18. Tambin puede calcular la edad que tena Pel al ganar Brasil su tercer campeonato mundial de
Futbol, si sabemos que naci el 23/oct/1940 y el tercer campeonato de Brasil fue en el Mundial de
Mxico y se obtuvo el 21/jun/1970 en el estadio Azteca venciendo a Italia por 4 1.
Biblioteca=# SELECT edad('23-10-1940', '1970/06/21') as "Edad de Pel";

19. Otro ejercicio sencillo consiste en crear una funcin para convertir una fecha a texto (el prefijo FM
elimina espacios en blanco innecesarios en los nombres del da y del mes):
Biblioteca=# CREATE FUNCTION fecha(f DATE) RETURNS text
Biblioteca-# AS 'SELECT TO_CHAR(f, ''FMDay DD" de "FMMonth" de "YYYY'')'
Biblioteca-# language 'sql';

20. Como ejemplo deber convertir a texto la fecha de hoy:


Biblioteca=# SELECT fecha(current_date);

21. Genere una imagen que evidencie la realizacin de la consulta.


22. Lo malo es que el nombre del da y el del mes aparecen en ingls.
23. En teora, la variable de sistema que determina esto se llama lc_time.
Biblioteca=# SHOW lc_time;

24. Sin embargo, aunque el valor de esta variable corresponda a Mxico, Spanish_Mexico.1252, sigue
mostrando los nombres de los meses y los das en ingls.
25. Un sencillo ejemplo de funcin en lenguaje procedural consiste en implementar la funcin factorial,
como se indica a continuacin:
Biblioteca=# CREATE OR REPLACE FUNCTION Factorial(N NUMERIC)
Biblioteca-# RETURNS NUMERIC
Biblioteca-# AS $$
Biblioteca$# DECLARE
Biblioteca$# FACT NUMERIC;
Biblioteca$# I NUMERIC;
Biblioteca$# BEGIN
Biblioteca$# FACT:=1;
Biblioteca$# FOR I IN 1 .. N LOOP
Biblioteca$# FACT:=FACT*I;
Biblioteca$# END LOOP;
Biblioteca$# RETURN FACT;
Biblioteca$# END; $$
Biblioteca-# LANGUAGE plpgsql;

26. Genere una imagen que evicencie la creacin de esta funcin.


27. Ahora ejectelo de la siguiente manera:
Biblioteca=# SELECT Factorial(5::NUMERIC);

28. Observe que puede calcular el factorial de nmeros ms grandes:


Biblioteca=# SELECT Factorial(45::NUMERIC);

29. Genere una imagen que evidencie la realizacin de la consulta.


30. Ahora va a crear un conjunto de reglas que eviten cualquier modificacin a la tabla Editoriales:
Biblioteca=# CREATE RULE prot1 AS ON INSERT TO "Libros" DO INSTEAD
NOTHING;
Taller de Bases de Datos Prctica 28

Biblioteca=# CREATE RULE prot2 AS ON UPDATE TO "Libros" DO INSTEAD


NOTHING;
Biblioteca=# CREATE RULE prot3 AS ON DELETE TO "Libros" DO INSTEAD
NOTHING;

31. Para probar las reglas, intente cada una de las siguientes operaciones:
Biblioteca=# SELECT * FROM "Libros";
Biblioteca=# INSERT INTO "Libros" VALUES ('Uno','Dos','Tres','Alfaguara'
,1,2,'Espanol');
Biblioteca=# UPDATE "Libros" SET "Precio"=100 WHERE "Precio"='$1.00';
Biblioteca=# DELETE FROM "Libros" WHERE "ISBN" LIKE '9%';

32. Podr constatar que aparentemente se ejecutaron las sentencias, ya que no ocurre ningn error,
pero tampoco se realiza ningn cambio en la tabla Libros:
Biblioteca=# SELECT * FROM "Libros";

33. Una forma ms sofisticada de utilizar el sistema de reglas consiste en crear una regla que registre
los datos de la persona y el momento en que se hizo un cambio de precio a un libro.
Biblioteca=# CREATE TABLE log (isbn CHAR(17), precio text, usuario text,
momento timestamp);
Biblioteca=# CREATE RULE cambio AS ON UPDATE TO "Libros" WHERE
NEW."Precio"!= OLD."Precio" DO INSERT INTO log VALUES (NEW."ISBN",
NEW."Precio",getpgusername(),current_timestamp);

34. Para probar esta regla primero deber eliminar una de las reglas previas, para que proceda la
actualizacin;
Biblioteca=# DROP RULE prot2 on "Libros";

35. Ahora repita la instruccin de actualizacin anterior:


Biblioteca=# UPDATE "Libros" SET "Precio"=100 WHERE "Precio"='$1.00';

36. Y observe que si se realiz el cambio de precio en todos los libros:


Biblioteca=# SELECT * FROM "Libros";

37. Entonces revise la nueva tabla de registro:


Biblioteca=# SELECT * FROM log;

38. Genere una imagen que evidencie la realizacin de la consulta.


39. Cierre la consola del monitor de comandos y la ventana del smbolo de sistema.
40. Fin de la Prctica

Evidencias
El alumno deber enviar al instructor las evidencias requeridas durante la realizacin de la prctica.

Sugerencias didcticas
El instructor deber atender a los alumnos que tengan dificultades en la interpretacin y la realizacin de
las instrucciones de la prctica.
Taller de Bases de Datos Prctica 28

Resultados
Se aprendi a crear funciones y definir reglas utilizando la herramienta PostgreSQL.

Bibliografa
http://es.tldp.org/Postgresql-es/web/navegable/user/sql-createfunction.html
http://es.tldp.org/Postgresql-es/web/navegable/user/sql-createrule.html

Вам также может понравиться