Está en la página 1de 30

GoBack

PostgreSQL Módulo 1 - Funciones

Rodrigo Soliz Rocabado (rodrifer@gmail.com)

June 14, 2007

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 1


Funciones

Funciones en PostgreSQL

Funciones en PL/pgsql

Partes de una función

Invocando a una función

Variables

Estructuras de control

IF

WHILE

FOR
Funciones
Trabajando con tablas

Variables compuestas

SELECT INTO

Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 2


Funciones en PostgreSQL

Funciones
PostgreSQL viene con muchas funciones incorporadas, podemos verlas todas dentro del
psql con el comando \df o examinando la tabla del sistema pg_proc
Funciones en PostgreSQL

Funciones en PL/pgsql

Partes de una función


SELECT * FROM pg_proc;
Invocando a una función

Variables

Estructuras de control
Pero nosotros podemos declarar nuestras propias funciones de acuerdo a las
IF necesidades de nuestra base de datos.
WHILE

FOR

Trabajando con tablas

Variables compuestas

SELECT INTO

Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 3


Funciones en PL/pgsql

Funciones
Uno de los lenguajes soportados para programar funciones en PostgreSQL es el
Funciones en PostgreSQL

Funciones en PL/pgsql
PL/pgsql, se desarrolló exclusivamente para él y es muy parecido al PL/SQL de Oracle.
Partes de una función Para poder utilizarlo primero debemos instalarlo en la base de datos que vayamos a
Invocando a una función utilizar:
Variables

Estructuras de control createlang plpgsql -d nombrebase -U nombreusuario


IF

WHILE o si ya estamos conectados a la base de datos:


FOR

Trabajando con tablas CREATE LANGUAGE plpgsql;


Variables compuestas

SELECT INTO
Nota: En la instalación de PostgreSQL para Windows el lenguaje procedural Pl/pgsql esta
Bucles en tablas
instalado desde el principio, en distribuciones GNU/Linux no.

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 4


Partes de una función

Funciones

Funciones en PostgreSQL CREATE FUNCTION nombrefuncion(param, param)


Funciones en PL/pgsql RETURNS tiporetorno
Partes de una función AS $$
Invocando a una función
DECLARE
Variables
variable;
Estructuras de control
variable;
BEGIN
IF
sentencia; -- esto es un comentario
WHILE
sentencia; /* esto es un bloque de comentario */
FOR
sentencia;
Trabajando con tablas RETURN retorno;
Variables compuestas END;
SELECT INTO $$
Bucles en tablas Language 'plpgsql';

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 5


Ejemplo

Funciones

Funciones en PostgreSQL CREATE FUNCTION suma (int4, int4)


Funciones en PL/pgsql RETURNS int4
Partes de una función AS $$
Invocando a una función
DECLARE
Variables
a int4;
Estructuras de control
b int4;
res int4;
IF
BEGIN
WHILE
a := $1;
FOR
b := $2;
Trabajando con tablas res := a + b;
Variables compuestas RETURN res;
SELECT INTO END;
Bucles en tablas $$
Language 'plpgsql';

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 6


Invocando a una función

Funciones
Como es que se invoca a una función?
Funciones en PostgreSQL

Funciones en PL/pgsql
Dentro una sentencia SELECT:
Partes de una función

Invocando a una función

Variables
SELECT suma(3, 4);
Estructuras de control

IF suma
WHILE ------
FOR 7
Trabajando con tablas

Variables compuestas

SELECT INTO

Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 7


Variables

Funciones
Como se asigna un valor a una variable?
Funciones en PostgreSQL

Funciones en PL/pgsql nombrevariable := valor ;


Partes de una función

Invocando a una función Ejemplo:


Variables

Estructuras de control aux := 1 ;


IF

WHILE Declarar una variable y asignarle un valor?


FOR

Trabajando con tablas nombrevariable tipovariable := valor ;


Variables compuestas

SELECT INTO Ejemplo:


Bucles en tablas
aux boolean := true ;

El uso de variables es idéntico a los lenguajes de programación que comunmente usamos.

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 8


Ejemplo (Recursión)

Funciones

Funciones en PostgreSQL CREATE FUNCTION fib(int4)


Funciones en PL/pgsql RETURNS int4
Partes de una función AS $$
Invocando a una función
DECLARE
Variables
a int4;
Estructuras de control
res int4 := 0;
BEGIN
IF
a := $1;
WHILE
IF ( a = 1 OR a = 2) THEN
FOR
res := 1;
Trabajando con tablas ELSE
Variables compuestas res := fib(a - 2) + fib(a - 1);
SELECT INTO END IF;
Bucles en tablas RETURN res;
END;
$$
Language 'plpgsql';

Asi es, tenemos la posibilidad de utilizar funciones recursivas.

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 9


Probémoslo

Funciones
Hagamos la prueba:
Funciones en PostgreSQL

Funciones en PL/pgsql SELECT fib(10);


Partes de una función

Invocando a una función fib


Variables ------
Estructuras de control 55
IF

WHILE Recomendación: dada la definición de nuestra función fib, no es recomendable calcular


FOR
números muy elevados, si es que no queremos que nuestro servidor se colapse ;-)
Trabajando con tablas

Variables compuestas

SELECT INTO

Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 10


Estructuras de control

Funciones
Podemos usar las estructuras de control más comunes disponibles en otros lenguajes de
Funciones en PostgreSQL

Funciones en PL/pgsql
programación:
Partes de una función

Invocando a una función


IF - THEN - ELSE
Variables FOR
Estructuras de control
WHILE
IF

WHILE
Adicionalmente tenemos el LOOP (ver documentación), pero no hace nada que las
FOR

Trabajando con tablas


anteriores no puedan lograr.
Variables compuestas

SELECT INTO

Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 11


IF

Funciones

Funciones en PostgreSQL CREATE FUNCTION espositivo (int4)


Funciones en PL/pgsql RETURNS boolean
Partes de una función AS $$
Invocando a una función
DECLARE
Variables
a int4;
Estructuras de control
res boolean := false;
BEGIN
IF
a := $1;
WHILE
IF (a > 0) THEN
FOR
res := true;
Trabajando con tablas ELSE
Variables compuestas IF (a = 0) THEN
SELECT INTO res := true;
Bucles en tablas END IF;
END IF;
RETURN res;
END;
$$
Language 'plpgsql';

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 12


WHILE

Funciones

Funciones en PostgreSQL CREATE FUNCTION adicion()


Funciones en PL/pgsql RETURNS int4
Partes de una función AS $$
Invocando a una función
DECLARE
Variables
cont int4;
Estructuras de control
res int4;
BEGIN
IF
cont := 1;
WHILE
res := 0;
FOR
WHILE (cont <= 10)
Trabajando con tablas LOOP
Variables compuestas res := res + cont;
SELECT INTO cont := cont + 1;
Bucles en tablas END LOOP;
RETURN res;
END;
$$
Language 'plpgsql';

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 13


FOR

Funciones

Funciones en PostgreSQL CREATE FUNCTION adicion2()


Funciones en PL/pgsql RETURNS int4
Partes de una función AS $$
Invocando a una función
DECLARE
Variables
cont int4;
Estructuras de control
res int4;
BEGIN
IF
res := 0;
WHILE
FOR cont IN 1 .. 10
FOR
LOOP
Trabajando con tablas res := res + cont;
Variables compuestas END LOOP;
SELECT INTO RETURN res;
Bucles en tablas END;
$$
Language 'plpgsql';

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 14


Trabajando con tablas

Funciones
Pero lo que nos interesa es trabajar con los datos de una tabla. Entonces veamos un
Funciones en PostgreSQL
ejemplo más práctico.
Funciones en PL/pgsql

Partes de una función Supongamos que tenemos una tabla ítem que almacena la información de piezas de
Invocando a una función hardware vendidas por una tienda de computadoras.
Variables

Estructuras de control CREATE TABLE item (


IF item_id serial NOT NULL,
WHILE nombre varchar(150) NOT NULL,
FOR
tipo varchar(100) NOT NULL,
Trabajando con tablas
cantidad int4 NOT NULL DEFAULT 0,
precio_compra numeric(7,2) NOT NULL,
precio_venta numeric(7,2) NOT NULL,
Variables compuestas

SELECT INTO
CONSTRAINT item_id_pk PRIMARY KEY (item_id)
Bucles en tablas
);

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 15


Trabajando con tablas

Funciones
Queremos que haya un función comprar_item() que haga lo siguiente:
Funciones en PostgreSQL

Funciones en PL/pgsql
1. Cree una tabla nueva llamada item_por_comprar que almacene los datos de los
Partes de una función

Invocando a una función


items que tengan cantidad = 0, o sea los items que hay que renovar para luego
Variables poner a la venta.
Estructuras de control

IF 2. Busque en la tabla item todos los items que ya no estén en stock y los inserte en
WHILE
la tabla item_por_comprar
FOR

Trabajando con tablas

Variables compuestas
3. Nos devuelva la cantidad de items que ya no se encuentran en stock
SELECT INTO

Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 16


Primeros pasos

Funciones
Primero creamos una tabla para almacenar los items que ya no hay disponibles en stock,
Funciones en PostgreSQL
la tabla item_por_comprar:
Funciones en PL/pgsql

Partes de una función


CREATE TABLE item_por_comprar (
Invocando a una función
item_id int4 NOT NULL,
Variables nombre varchar(150)
Estructuras de control );
IF

WHILE
Esta tabla contiene información que solo es importante momentáneamente, no nos
FOR

Trabajando con tablas


interesa almacenarla permanentemente en la base de datos, por lo que la
Variables compuestas reemplazaremos cada vez que ejecutemos la función.
SELECT INTO

Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 17


La función

Funciones
Empezamos a definir la función:
Funciones en PostgreSQL

Funciones en PL/pgsql CREATE OR REPLACE FUNCTION comprar_item()


Partes de una función RETURNS int4
Invocando a una función AS $$
Variables DECLARE
Estructuras de control cont_item int4;
IF fila_item item%ROWTYPE;
WHILE
BEGIN
FOR
...
END;
$$
Trabajando con tablas

Variables compuestas
Language 'plpgsql';
SELECT INTO

Bucles en tablas
Declaramos dos variables, cont_item que tendrá el número de items que tengan
cantidad = 0 y fila_item que tendrá como campos, los atributos de la tabla item.

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 18


Variables compuestas

Funciones
Podemos declarar variables compuestas que puedan almacenar los campos de una
Funciones en PostgreSQL
determinada fila de una determinada tabla.
Funciones en PL/pgsql

Partes de una función


fila_item item%ROWTYPE ;
Invocando a una función

Variables

Estructuras de control
Indica que la variable fila_item podrá almacenar los campos de cualquier fila de la tabla
IF item.
WHILE Para acceder a los valores de la variable fila_item usamos una notación ya conocida:
FOR

Trabajando con tablas fila_item.nombre


Variables compuestas fila_item.cantidad
SELECT INTO fila_item.precio_compra
Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 19


Continuamos con la función

Funciones

Funciones en PostgreSQL CREATE OR REPLACE FUNCTION comprar_item()


Funciones en PL/pgsql RETURNS int4
Partes de una función AS $$
Invocando a una función
DECLARE
Variables
cont_item int4;
Estructuras de control
fila_item item%ROWTYPE;
BEGIN
IF
DROP TABLE item_por_comprar;
WHILE
CREATE TABLE item_por_comprar (item_id int4 NOT NULL,
FOR
nombre varchar(150));
Trabajando con tablas END;
Variables compuestas $$
SELECT INTO Language 'plpgsql';
Bucles en tablas

Cada vez que vayamos a ejecutar la función borraremos la anterior tabla y crearemos una
nueva con datos actualizados. No nos interesa almacenar la información que se genera
cada vez que ejecutamos la función, solo la información más reciente.

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 20


Continuamos con la función

Funciones

Funciones en PostgreSQL CREATE OR REPLACE FUNCTION comprar_item()


Funciones en PL/pgsql RETURNS int4
Partes de una función AS $$
Invocando a una función
DECLARE
Variables
cont_item int4;
Estructuras de control
fila_item item%ROWTYPE;
BEGIN
IF
DROP TABLE item_por_comprar;
WHILE
CREATE TABLE item_por_comprar (item_id int4 NOT NULL,
FOR
nombre varchar(150));
Trabajando con tablas SELECT COUNT(*) INTO cont_item FROM item WHERE cantidad = 0;
Variables compuestas END;
SELECT INTO $$
Bucles en tablas Language 'plpgsql';

Almacenamos en cont_item la cantidad de items que tienen cantidad = 0

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 21


SELECT INTO

Funciones
Podemos asignar un valor a una variable directamente dentro de una consulta SQL
Funciones en PostgreSQL

Funciones en PL/pgsql SELECT COUNT(*) INTO cont_item FROM item WHERE cantidad = 0;
Partes de una función

Invocando a una función


cont_item es una variable tipo int4 y la consulta también devuelve un tipo compatible, por
Variables

Estructuras de control
lo tanto en cont_item tendremos un valor correcto.
IF

WHILE

FOR

Trabajando con tablas

Variables compuestas

SELECT INTO

Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 22


Continuamos con la función

Funciones

Funciones en PostgreSQL CREATE OR REPLACE FUNCTION comprar_item()


Funciones en PL/pgsql RETURNS int4
Partes de una función AS $$
Invocando a una función
DECLARE
Variables
cont_item int4;
Estructuras de control
fila_item item%ROWTYPE;
BEGIN
IF
DROP TABLE item_por_comprar;
WHILE
CREATE TABLE item_por_comprar (item_id int4 NOT NULL,
FOR
nombre varchar(150));
Trabajando con tablas SELECT COUNT(*) INTO cont_item FROM item WHERE cantidad = 0;
Variables compuestas FOR fila_item IN SELECT * FROM item WHERE cantidad = 0
SELECT INTO LOOP
Bucles en tablas INSERT INTO item_por_comprar
VALUES (fila_item.item_id, fila_item.nombre);
END LOOP;
END;
$$
Language 'plpgsql';

Definimos un bucle que recorra la tabla temporal que tiene los items con cantidad = 0 y
por cada una insertamos una fila en la tabla item_por_comprar

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 23


Bucles en tablas

Funciones
Vimos que podiamos definir un bucle con la sentencia FOR de esta forma:
Funciones en PostgreSQL

Funciones en PL/pgsql FOR variable IN rango


Partes de una función

Invocando a una función


Si trabajamos con variables compuestas y tablas, podemos colocar en variable una
Variables

Estructuras de control
variable compuesta y en rango una tabla cualquiera (o un subconjunto), la variable
IF compuesta recorrerá toda la tabla tomando los valores de cada una de las filas, si tienen
WHILE los mismos atributos por supuesto.
FOR

Trabajando con tablas FOR fila_item IN SELECT * FROM item WHERE cantidad = 0;
Variables compuestas

SELECT INTO

Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 24


Continuamos con la función

Funciones

Funciones en PostgreSQL CREATE OR REPLACE FUNCTION comprar_item()


Funciones en PL/pgsql RETURNS int4
Partes de una función AS $$
Invocando a una función
DECLARE
Variables
cont_item int4;
Estructuras de control
fila_item item%ROWTYPE;
BEGIN
IF
DROP TABLE item_por_comprar;
WHILE
CREATE TABLE item_por_comprar (item_id int4 NOT NULL,
FOR
nombre varchar(150));
Trabajando con tablas SELECT COUNT(*) INTO cont_item FROM item WHERE cantidad = 0;
Variables compuestas FOR fila_item IN SELECT * FROM item WHERE cantidad = 0
SELECT INTO LOOP
Bucles en tablas INSERT INTO item_por_comprar
VALUES (fila_item.item_id, fila_item.nombre);
END LOOP;
RETURN cont_item;
END;
$$
Language 'plpgsql';

Finalmente retornamos cont_item para saber cuantos items han sido insertados.

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 25


Probando la función

Funciones
Probemos insertando algunas filas en la tabla item:
Funciones en PostgreSQL

Funciones en PL/pgsql INSERT INTO item (nombre, tipo, cantidad, precio_compra, precio_venta)
Partes de una función VALUES ('Switch Dlink 8 puertos', 'Switch', 2, 32.5, 45.6);
Invocando a una función INSERT INTO item (nombre, tipo, cantidad, precio_compra, precio_venta)
Variables VALUES ('Dlink 56K', 'Modem', 0, 10.5, 15.5);
Estructuras de control INSERT INTO item (nombre, tipo, cantidad, precio_compra, precio_venta)
IF VALUES ('Samsung 17', 'Monitor', 0, 100.0, 120.0);
WHILE
INSERT INTO item (nombre, tipo, cantidad, precio_compra, precio_venta)
FOR
VALUES ('DDR2 512/533', 'RAM', 15, 40.0, 45.0);
INSERT INTO item (nombre, tipo, cantidad, precio_compra, precio_venta)
VALUES ('NVIDIA GEFORCE FX 5200', 'Tarjeta de Video', 7, 40.0, 48.5);
Trabajando con tablas

Variables compuestas
INSERT INTO item (nombre, tipo, cantidad, precio_compra, precio_venta)
SELECT INTO
VALUES ('Pentium 4 3.2 GHZ 800/2MB', 'Procesador', 7, 200.0, 230.0);
Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 26


Probando la función

Funciones
Ejecutemos la función:
Funciones en PostgreSQL

Funciones en PL/pgsql SELECT comprar_item();


Partes de una función

Invocando a una función


Veámos el contenido de la tabla item_por_comprar:
Variables

Estructuras de control SELECT * FROM item_por_comprar;


IF

WHILE

FOR

Trabajando con tablas

Variables compuestas

SELECT INTO

Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 27


Una variante de la funcion anterior

Funciones
Utilicemos la misma tabla item y hagamos una función patrimonio() que nos retorne:
Funciones en PostgreSQL

Funciones en PL/pgsql
 El valor total de todos los items disponibles en la tienda.
Partes de una función

Invocando a una función

Variables
o sea :
Estructuras de control

IF cantidad x precio_venta (de cada item)


WHILE

FOR

Trabajando con tablas

Variables compuestas

SELECT INTO

Bucles en tablas

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 28


Una variante de la función anterior

Funciones

Funciones en PostgreSQL CREATE OR REPLACE FUNCTION patrimonio()


Funciones en PL/pgsql RETURNS numeric(7,2)
Partes de una función AS $$
Invocando a una función
DECLARE
Variables
total numeric(7,2);
Estructuras de control
fila_item item%ROWTYPE;
BEGIN
IF
total := 0.0;
WHILE
FOR fila_item IN SELECT * FROM item WHERE cantidad != 0
FOR
LOOP
Trabajando con tablas total := total + fila_item.cantidad * fila_item.precio_venta ;
Variables compuestas END LOOP;
SELECT INTO RETURN total;
Bucles en tablas END;
$$
Language 'plpgsql';

Veamos como el tipo de retorno de la funcion ha cambiado, ya no es int4 sino numeric.

http://www.postgresql.org PostgreSQL Módulo 1 – Slide 29

También podría gustarte