Está en la página 1de 51

CREACIÓN

DE UNA
BASE
DE
DATOS
CREACION DE UNA BASE DE DATOS

Prácticamente, la creación de la base de datos consiste en la creación de las tablas que la


componen. Así que para la creación de una nueva base de datos se debe dar clic en una de las
bases de datos que están creadas y abrir un nuevo texto de consultas.
GRAFICO

La sintaxis empleada por PostgreSQL, pero también por las DBMS más difundidas, es la siguiente:

CREATE DATABASE nombre_base_de_datos

Ejemplo:
CREATE DATABASE PEDIDOS

Creación de Tablas

Las tablas forman parte de una base de datos, como se dijo anteriormente entonces para crear una
tabla debemos resolver qué campos (columnas) tendrá y qué tipo de datos almacenarán cada uno
de ellos, es decir, su estructura.

Sintaxis:

create table NOMBRETABLA(


NOMBRECAMPO1 TIPODEDATO,
...

NOMBRECAMPON TIPODEDATO
);

Ejemplo

CREATE TABLE EMPLEADOS(


EMPLEADOID int NOT NULL,
NOMBRE char(30) NULL,
APELLIDO char(30) NULL,
FECHA_NAC date NULL,
REPORTA_A int NULL,
EXTENSION int NULL,
CONSTRAINT PK_EMPLEADOS PRIMARY KEY (EMPLEADOID));
DROP TABLE

El comando DROP TABLE permite eliminar una tabla, incluyendo todas las tuplas almacenadas en
ella:

Sintaxis: DROP TABLE table_name;


Ejemplo:

DROP TABLE CATEGORIAS;

INSERT INTO

Para llenar una tabla previamente creada se hace el uso del comando INSERT INTO, que permite
llenar todos los campos que la tabla tiene.

Sintaxis:
INSERT INTO table_name (name_of_attr_1
[, name_of_attr_2 [,...]])
VALUES (val_attr_1
[, val_attr_2 [ ...]]);

Ejemplo:

insert into categorias (categoriaid, nombrecat) values (100, ‘CARNICOS’);


insert into categorias (categoriaid, nombrecat) values (200, ‘LACTEOS’);
insert into categorias (categoriaid, nombrecat) values (300, ‘LIMPIEZA’);

FUNCION UPDATE

Cambia los valores de columnas especificadas en todas las flas que satisfagan cierta condición. En
la clausula SET se deben mencionar solamente las columnas a ser modificadas; el resto de
columnas no mencionadas retendrán sus valores anteriores.
Por defecto, UPDATE puede actualizar una tabla específica y todas sus subtablas. Si se desea
actualizar únicamente cierta tabla, se debe utilizar la clausula ONLY.

Existen dos maneras de modificar una tabla utilizando la información contenida en otras tablas en la
base de datos: utilizando subconsultas o especificando las tablas adicionales en la clausula FROM.
La técnica más apropiada depende de las circunstancias específicas.
Sintaxis:

UPDATE [ ONLY ] table SET column = { expression | DEFAULT } [, ...]

[ FROM fromlist ]

Donde:

 table: Nombre de la tabla a actualizar.


 column: Nombre de la columna de la tabla. El nombre de la columna puede calificarse como
nombre de un subcampo o subíndice del arreglo, si es necesario.
 expression: Expresión para asignar a la columna. La expresión podría utilizar los antiguos
valores de esa y otras columnas en la tabla.
 DEFAULT: Asigna el valor predefinido a la columna (qué será NULL si ninguna expresión
predefinida específica se ha asignado a él).
 fromlist: Una lista de expresiones de la tabla, permitiendo la aparición de columnas de otras
tablas en la condición WHERE y las expresiones de actualización. Esto es similar a la lista
de tablas en que pueden especificarse en la función FROM de una sentencia SELECT. La
tabla designada no debe aparecer en el fromlist, a menos que se inserte un self-join (en tal
caso debe aparecer con un alias).
 condition: Una expresión que devuelve un valor del tipo booleano. Solamente pueden
actualizadas las flas para las cuales devuelve el valor true.
 UPDATE count: count es el número de flas actualizadas. Si el valor de count es igual a
cero, ninguna fila cumple con la condición (no quiere decir que ha ocurrido un error).

Nota: Cuando una clausula FROM está presente, lo que ocurre esencialmente es que la tabla
designada se une a las tablas mencionadas en el fromlist, y cada fila resultante en la unión
representa una operación de actualización para las tablas designadas. Cuando se utiliza FROM se
debe asegurar que la unión produce a lo mucho una fila resultante para cada fila a ser modificada.
En otras palabras, una fila designada no debe unir a más de una fila en la otra tabla(s). Si lo hace,
entonces solamente se utilizará una fila para actualizarla cuya selección es aleatoria.

Debido a esta indeterminación, es más seguro hacer referencia a otras tablas dentro de
subconsultas de SELECT, aunque a menudo es más difícil leer y más retardado que utilizando una
unión.
Ejemplo:

Actualizar el nombre de la categoría HIGINE PERSONAL a HIGIENE PERSONAL, en la columna


nombrecat:

UPDATE CATEGORIAS SET nombrecat = ‘HIGIENE PERSONAL’ WHERE nombrecat = ‘HIGINE


PERSONAL’;

ALTER TABLE: Cambia la definición de una tabla existente. Existen varias de sus formas:

ADD COLUMN: Añade una nueva columna a la tabla utilizando la misma sintaxis que CREATE
TABLE.

DROP COLUMN: Elimina una columna de la tabla. Los índices y constraints que involucra la
column deberán ser automáticamente borrados también. Si algún elemento externo depende de la
columna, será necesario utilizar la clausula CASCADE, por ejemplo, referencias a clave foráneas o
vistas.

SET/DROP DEFAULT: Coloca o remueve el valor predefinido de una columna. El valor predefinido
sólo se aplica las órdenes INSERT subsecuentes. También pueden crearse valores predeterminados
para vistas, en el caso en que son insertadas en las declaraciones INSERT antes de que la regla de
la vista ON INSERT sea aplicada.

SET/DROP NOT NULL: Cambian si una columna es marcada para permitir valores o rechazar los
valores nulos.

SET STATISTICS: Coloca un valor de estadísticas recogidas por columna para una operación
ANALIZE subsecuente. El valor puede estar en el rango de 0 a 1000; alternativamente, se usa -1
para revertir el uso del sistema de valores de estadísticas predeterminado.

SET STORAGE: Define el modo de almacenamiento de una columna. Este controla si dicha
columna depende de otra tabla suplementaria, y si los datos deben comprimirse o no. PLAIN debe
utilizarse para valores de longitud fija como el entero interno no comprimible. MAIN es para datos
ligados comprimibles. EXTERNAL es para datos externos no comprimibles, y EXTENDED es para
datos externos comprimibles. EXTENDED es el valor predeterminado para todo tipo de datos que lo
soportan.
SET WITHOUT OIDS: Quita el identificador de columna de la tabla. La remoción de OIDs de una
tabla no ocurre inmediatamente. El espacio que ocupa el OID se guardará cuando la fila sea
actualizada. Si no se actualiza la fila, el espacio y el valor del OID son guardados indefinidamente.
Esta semántica es similar a la del proceso DROP COLUMN.

RENAME: Cambia el nombre de una tabla (o un índice, secuencia, o vista) o el nombre de una
columna individual en la tabla. No hay efecto en el almacenamiento de datos.

ADD table_constraint: Añade un nuevo constraint a la tabla usando la misma sintaxis que CREATE
TABLE.

DROP CONSTRAINT: Elimina los constraints de una tabla. Actualmente, los constraints de las
tablas no requieren tener nombres únicos, entonces puede haber más de un constraint identificados
los cuales serán eliminados.

OWNER: Cambia el propietario de una tabla, índice, secuencia, o vista de un usuario especificado.

CLUSTER: Marca una tabla para futuras operaciones CLUSTER. La clausula ALTER TABLE solo
puede ser ejecutada por el propietario de la tabla, mientras la clausula ALTER TABLE OWNER, sólo
puede ser ejecutada por un superusuario.
Sintaxis:

ALTER TABLE [ ONLY ] name [ * ]


ADD [ COLUMN ] column type [ column_constraint [ ... ] ]

ALTER TABLE [ ONLY ] name [ * ]


DROP [ COLUMN ] column [ RESTRICT | CASCADE ]

ALTER TABLE [ ONLY ] name [ * ]


ALTER [ COLUMN ] column { SET DEFAULT expression |
DROP DEFAULT }

ALTER TABLE [ ONLY ] name [ * ]


ALTER [ COLUMN ] column { SET | DROP } NOT NULL

ALTER TABLE [ ONLY ] name [ * ]


ALTER [ COLUMN ] column SET STATISTICS integer

ALTER TABLE [ ONLY ] name [ * ]


ALTER [ COLUMN ] column SET STORAGE { PLAIN |
EXTERNAL | EXTENDED | MAIN }

ALTER TABLE [ ONLY ] name [ * ]


SET WITHOUT OIDS

ALTER TABLE [ ONLY ] name [ * ]


RENAME [ COLUMN ] column TO new_column

ALTER TABLE name


RENAME TO new_name

ALTER TABLE [ ONLY ] name [ * ]


ADD table_constraint

ALTER TABLE [ ONLY ] name [ * ]


DROP CONSTRAINT constraint_name [ RESTRICT |
CASCADE ]

ALTER TABLE name


OWNER TO new_owner

ALTER TABLE name


CLUSTER ON index_name
Donde:

 name: Nombre de una tabla existente para alterarla. Si se desea alterar una sola tabla, se
debe utilizar la clausula ONLY. Caso contrario, se alterarán la tabla y todas las tablas que
desciendan de ésta.
 column: Nombre de una columna ya existente o nueva.
 type: Tipo de dato para la nueva columna.
 new_column: Nombre nuevo para una columna existente.
 new_name: Nombre nuevo para la tabla.
 table_constraint: Nuevo constraint para la tabla.
 constraint_name: Nombre de un constraint existente para eliminarlo.
 new_owner: Nombre del usuario o del nuevo propietario de la tabla.
 index_name: Nombre del índice que indica la tabla marcada para CLUSTER.
 CASCADE: Elimina automáticamente objetos que dependen de una columna o constraint
eliminado.
 RESTRICT: Negación a eliminar la columna o constraint si hay objetos dependientes. Esta
es una conducta predeterminada.

Notas: La palabra clave columna puede ser omitida. En la implementación actual de las clausulas
ADD COLUMN, default y NOT NULL para la nueva columna no son soportadas. La nueva columna
siempre entra teniendo todos los valores nulos. Se puede utilizar la forma SET DEFAULT de ALTER
TABLE para poner el valor predeterminado después. Para marcar la columna como no nula, se
utiliza la forma SET NOT NULL, después de haber ingresado los valores no nulos el las flas de la
columna.

La forma DROP COLUMN no elimina la columna físicamente, simplemente la hace invisible para las
operaciones de SQL. Subsecuentemente las operaciones INSERT y UPDATE podrían almacenar
valores nulos en esta columna.

Así, eliminar una columna es fácil pero no reduce inmediatamente el tamaño en disco de la tabla, ya
que el espacio ocupado por la tabla eliminada no puede reutilizarse a menos que se realice una
operación UPDATE sobre las flas.

Si una tabla tiene tablas descendientes, no es permitido añadir o renombrar una columna en la tabla
padre sin hacer lo mismo en las descendientes. Es decir, ALTER TABLE ONLY será rechazado.
Esto asegura que las tablas descendientes siempre estén emparejadas a la tabla padre.
Una operación recursiva DROP COLUMN sólo quitará la columna de una tabla descendiente, si ésta
no hereda esa columna de cualquier padre. Una operación no recursiva DROP COLUMN (ALTER
TABLE ONLY… DROP COLUMN) nunca remueve columnas descendientes, en cambio las marca
como herencia.

Ejemplos:

 Añadir una nueva columna del tipo varchar a la tabla EMPLEADOS:

ALTER TABLE EMPLEADOS ADD COLUMN Direccion varchar(30);

 Eliminar una columna de una tabla:

ALTER TABLE EMPLEADOS DROP COLUMN Direccion RESTRICT;

 Renombrar una columna existente de la tabla DETALLE_ORDENES

ALTER TABLE DETALLE_ORDENES RENAME COLUMN CANTIDAD TO QUANTITY;


CONSULTAS
SQL
CONSULTAS SQL

WHERE: En este ejemplo sólo se devuelven las flas de la tabla Productos que suministra el
proveedor de código 10 y el producto que entrega es ‘SALCHICHAS’

SELECT descripcion, preciounit AS “Precio unitario”


FROM productos
WHERE proveedorid = 10
AND descripcion LIKE ‘SALCHICHAS %’
 Operadores de comparación (como =, < >, < y >).

-- Muestre los productos que tengan un precio mayor a 2.60

SELECT descripcion, preciounit AS “Precio unitario”


FROM productos
WHERE preciounit >2.60

 Intervalos (BETWEEN y NOT BETWEEN).

-- Muestre los productos con precios entre 9 y 15

SELECT descripcion, preciounit AS “Precio unitario”


FROM productos
WHERE preciounit BETWEEN 9 AND 15
ORDER BY preciounit

-- Muestre los productos con precios fuera de 9 y 15

SELECT descripcion, preciounit AS “Precio unitario”


FROM productos
WHERE preciounit NOT BETWEEN 9 AND 15
ORDER BY preciounit

 Listas (IN, NOT IN).

-- Muestre las categorías que sean CARNICOS, LACTEOS o MEDICINAS

SELECT *
FROM categorias
WHERE nombrecat IN (‘CARNICOS’,’LACTEOS’,’MEDICINAS’)
 Coincidencia de modelos (LIKE y NOT LIKE).

-- Muestre los empleados cuyo nombre empiece con J

SELECT *
FROM empleados
WHERE nombre LIKE ‘J%’

-- Muestre los empleados cuyo nombre no empiece con J

SELECT *
FROM empleados
WHERE nombre NOT LIKE ‘J%’

 Valores NULL (ISNULL y NOTNULL).

--Muestra las órdenes donde no existe descuento

SELECT *
FROM ordenes
WHERE descuento ISNULL

--Muestra las órdenes donde existe descuento

SELECT *
FROM ordenes
WHERE descuento NOTNULL
FUNCIONES
FUNCIONES

EL LENGUAJE DE FUNCIONES PL/pgSQL

Una de las características de PostgreSQL es que permite al usuario o administrador de la base de


datos escribir sus propias funciones dentro de la base de datos, estas funciones se almacenan y
ejecutan desde el proceso de base de datos y no desde la aplicación del cliente.

PostgreSQL permite en este sentido crear sus funciones de usuario o comúnmente llamadas
“PROCEDIMIENTOS ALMACENADOS” no solo en lenguaje SQL que es un lenguaje que carece de
estructuras de control como IF, WHILE, FOR y otros, sino que permite definir un lenguaje propio y
extenderlo a la base de datos, es así como están disponibles para Postgre los siguientes lenguajes:
C, Perl, Phyton, PHP entre otros.

Estos lenguajes deben ser instalados en la base de datos previamente antes de ser utilizados.

Sin embargo, también 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, es este lenguaje de funciones en el que concentraremos este manual.

VENTAJAS DEL USO DE FUNCIONES

 Desde el momento en que podemos crear nuestras propias funciones en la base de datos,
obtenemos una serie de ventajas en nuestras aplicaciones, es así como podemos
mencionar las siguientes ventajas del uso de funciones definidas por el usuario.

 Se pueden crear funciones para ser ejecutadas en algún evento de la base de datos. Al
borrar, modificar o insertar datos por ejemplo.

 Se pueden añadir estructuras de control al lenguaje SQL, podemos ahora definir ciclos de
ejecución como FOR y WHILE que nos permitan recorrer variables de tipo array, tablas u
otras estructuras.

 Las funciones nos permiten realizar cálculos 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.

 Se pueden heredar todos los tipos definidos por el usuario, las funciones y los operadores,
esta característica nos permite tomar variables de tipo registro o fila (RECORD o ROW) y
permitirnos procesar sus datos.
 Nos aporta una ejecución fable para el servidor, es decir, podemos estar seguros de de el
conjunto de instrucciones de la función definida se ejecutará, sin importar si ocurren
problemas en el cliente, en una conexión o enlace, una vez solicitada la función esta se
ejecuta en modo seguro y protegido en el servidor.

NOTA: Es un lenguaje fácil de usar, pues extiende de una manera simplista pero a la vez potente el
lenguaje SQL.

DESCRIPCION DEL LENGUAJE

ESTRUCTURA DE PL/pgSQL

El lenguaje PL/pgSQL no es sensible al reconocimiento de mayúsculas. Todas las palabras clave e


identificadores pueden usarse en cualquier mescla de mayúsculas y minúsculas, sin embargo, de
preferencia, el nombre de tablas y de registros utilice según definió en la base de datos.

PL/pgSQL es un lenguaje orientado a bloques. la estructura básica del lenguaje se define de la


siguiente manera :

CREATE [OR REPLACE] FUNCTION <nombre_de_funcion> ([lista de parámetros])


RETURNS <tipo_de_retorno> AS $$
DECLARE
<declaración de variables locales de la función>
BEGIN
<sentencias propias de la función>
END;
$$LANGUAGE ‘plpgsql’;

DEFINIENDO LOS PARAMETROS DE LAS FUNCIONES

Una de las características de PL/pgSQL es que no es necesario definir los nombres de variables en
la función, sólo es necesario definir si tipo, de de esta manera tenemos que una función puede ser
definida en términos de parámetros de entrada y salida de la siguiente forma :

FUNCTION suma ( real , real )


RETURNS real AS ‘
/*...resto de la funcion... */

En este ejemplo definimos la función “suma” con dos parámetros de entrada de tipo real y también la
salida o RETURNS de tipo real. Cabe notar que podemos utilizar como parámetros 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 instrucción CREATE
TYPE.

DEFINICION DE VARIABLES LOCALES O DE FUNCION

Como explicamos anteriormente, las variables locales son definidas dentro de la sección DECLARE
de la función, de forma muy similar a otros lenguajes podemos definir variables, por ejemplo:

DECLARE
contador integer = 0;
cadena varchar;
fecha date;
continuar bool;
suma real;

En este caso definimos una serie de variables con su tipo de dato, también, podemos definir una
variable y asignarle un valor en la misma línea de código de la definición de la variable (note la
variable “contador” inicializada en cero).

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... */

Continuando nuestra función suma, podemos apreciar que en la definición de variables usamos una
nomenclatura especial para asignar nombres de variable a los parámetros de entrada, de hecho, si
no hace esta redefinición, puede los parámetros asignando “$” y el número indicador en la lista de
parámetros a cada variable de parámetro, por ejemplo:
valor_total = $1 + $2;

ASIGNACION DE LAS SENTENCIAS DE PL/pgSQL

Una vez definidos los parámetros de entrada/salida, y también nuestras variables locales, podemos
comenzar a trabajar en nuestra función en la sección BEGIN .... END;

Las asignaciones de valores se realizan de la misma forma que en PASCAL, es decir, utilizando =
como operador de asignación y punto y coma al final de la línea, 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... */

Como vemos en este ejemplo la asignación de valores es prácticamente igual a PASCAL.

RETORNANDO EL UN VALOR COMO FUNCION

Finalmente una vez procesados nuestros valores debemos retornar algún valor (pues ese es la
esencia de la función), este retorno de valores también se realiza dentro de la sección BEGIN de la
función, pero utilizando la siguiente forma básica :

/*...resto de la funcion... */
RETURN <variable>;
/*...resto de la funcion... */

Ejemplo completo de la función SUMA:

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;
RETURN valor_total;
END;
$$LANGUAGE ‘plpgsql’;

Poco a poco hemos ido creando esta función, ahora está terminada y lista para ser utilizada.
ASIGNANDO COMENTARIOS

Si así lo necesitas, puedes documentar tus funciones usando los operadores /* ... */ para crear un
comentario de bloque multilinea o bien -- para un comentario de línea sencilla,

Ejemplo :

/*...resto de la función... */
/* Este es un comentario
que utiliza multiples líneas de comentario */
-- Este es un comentario en una sola línea
/*...resto de la función... */

UTILIZANDO SENTENCIAS DE CONTROL

Podemos utilizar sentencias de control para escribir nuestros programas y permitir que sigan un
algoritmo no lineal, para ello, contamos básicamente con las siguientes estructuras:

LOOP
EXIT
IF, ELSE
FOR
WHILE

SENTENCIA DE CICLO LOOP

Esta sentencia nos permite efectuar un ciclo, su estructura básica es:

/*...resto de la funcion... */
LOOP
...sentencias a ejecutar en el ciclo...
END LOOP
/*...resto de la funcion... */

SENTENCIA DE SALIDA EXIT:

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á acompañado con la sentencia IF, por ejemplo
LOOP
/*...resto de la funcion... */
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 funcion... */

SENTENCIAS IF, ELSE:

Podemos efectuar operaciones de comparación con las sentencias IF, ELSE, los operadores de
comparación son los siguientes:

< menor que...


> mayor que...
<> distinto a...
<= menor o igual que...
>= mayor o igual que...
= igual que...
OR o...
AND y...

Ejemplo:

/*...resto de la funcion... */
IF >= 10 or THEN
RETURN true;

ELSE
RETURN false;
END IF;
/*...resto de la funcion... */

SENTENCIA DE CICLO FOR

Existen dos tipos de ciclos FOR, el primero tiene que ver claramente con los ciclos numéricos
comunes, es decir, lo que comúnmente 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...
END LOOP;

Ejemplo:

/*...resto de la funcion... */
FOR inc IN 1..10 LOOP
factorial = factorial * inc;
END LOOP;
RETURN factorial;
/*...resto de la funcion... */

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;

Ejemplo:

/*...resto de la funcion... */
DECLARE
registro RECORD;
BEGIN
FOR registro IN SELECT * FROM productos LOOP
stock = registro.sock_actual + 100;
/*... otras sentencias... */
END LOOP;
/*...resto de la funcion... */
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.

SENTENCIA DE CICLO CONDICIONAL WHILE

La sentencia WHILE se ejecuta de forma muy similar a otros lenguajes de programación, su


estructura es la siguiente:

WHILE <condicion> LOOP


... SENTENCIAS A EJECUTAR DENTRO DEL CICLO WHILE...
END LOOP;

Ejemplo:

/*...resto de la funcion... */
WHILE inc <= 10 LOOP
factorial = factorial * inc;
END LOOP;
RETURN factorial;
/*...resto de la funcion...*/

Este código funciona igual al descrito en el ejemplo del ciclo FOR.

EJEMPLOS COMBINANDO PL/pgSQL con SQL

Una de las características que hacen de este lenguaje una herramienta poderosa, es la capacidad
de interactuar con SQL, obtener datos y procesarlos, la forma de utilizar SQL es tan familiar que solo
basta realizar los comandos SQL para ejecutar o procesar los datos necesarios.

Ejemplo 1: Buscar un cliente y retornar si existe o no

CREATE OR REPLACE FUNCTION buscar_cliente (varchar)


RETURNS bool AS ‘
DECLARE
ruc_buscar alias for $1;
registro clientes%ROWTYPE;
/* Aqui se defne la variable registro del tipo FILA de clientes indicando la tabla, el
simbolo % y luego la palabra reservada ROWTYPE */
BEGIN
SELECT INTO registro * FROM clientes
WHERE ruc_cliente = ruc_buscar;
IF FOUND THEN
RETURN true;
END IF;
RETURN false;
END;
$$LANGUAGE ‘plpgsql’;

Como podemos apreciar, este código busca un cliente en la tabla de clientes, si existe o se
encuentra el cliente, la función devolverá un valor verdadero (true), de lo contrario, ésta devolverá
falso (false).

Ejemplo 2: Buscar un producto y actualiza su precio según porcentaje

CREATE OR REPLACE FUNCTION actualizar_producto (varchar, varchar, real)


RETURNS bool AS ‘
DECLARE
producto ALIAS FOR $1;
porcentaje ALIAS FOR $2;
categoria ALIAS FOR $3;
registro productos%ROWTYPE;
BEGIN
SELECT INTO registro * FROM productos
WHERE productoid = producto;
IF FOUND THEN
UPDATE productos SET
PRECIOUNIT = PRECIOUNIT + (PRECIOUNIT * porcentaje)
WHERE categoriaid = categoria;
RETURN true;
END IF;
RETURN false;
END;
$$LANGUAGE ‘plpgsql’;

 Este código busca el producto, obtiene los datos necesarios y actualiza el registro.

Ejemplo 3: Incrementar valores según el porcentaje de IVA

CREATE OR REPLACE FUNCTION inc_iva (integer, real)


RETURNS integer AS ‘
DECLARE
valor ALIAS FOR $1;
iva ALIAS FOR $2;
total real;
BEGIN
total = valor + (valor * iva);
RETURN total;
RETURN;
END;
$$LANGUAGE ‘plpgsql’;

Esta función no actualiza realmente los datos de la tabla, solamente los procesa parámetros, de tal
manera que si los datos ingresados fueran los de una tabla devolvería el valor mas IVA.

LLAMANDO A LAS FUNCIONES

Hasta ahora hemos descrito a grandes rasgos como construir fácilmente funciones de usuario o
procedimientos almacenados, pero todavía no los hemos invocado, a continuación ejemplos de
llamadas a los procedimientos almacenados o funciones en PL/pgSQL:

Este ejemplo retornará true si el cliente SELECT buscar_


existe o fase si no se encuentra en la tabla cliente(‘1710185883’);
de clientes.
El producto “PRO-0540” actualizará su SELECT actualizar_producto(‘PRO-
precio en un 3% más. 0540’,0.03)
Sumará 2 números y retornara su valor SELECT suma(5.45, 10.452)
Retornará si el RUT está validado o no pero SELECT valida_ruc (ruc_cliente),
analizará todos los registros de la tabla. nombres, apellidos
FROM clientes
Esta sentencia utiliza la funcion que SELECT
incrementa los precios con IVA y renombra codigo,nombre, descripcion,
la salida de la funcion inc_iva a “precio_ inc_iva(precio_venta,0.18) AS precio_
iva”. iva
FROM productos
Funciones SQL

“Funciones SQL” son construcciones definidas por el estándar SQL92, que tiene sintaxis igual que
funciones pero que no pueden ser implementadas como simples funciones.

Funciones Retorna Descripción Ejemplo


COALESCE(list) no-NULO retorna el primer COALESCE(r”le>,
valor no-NULO en c2 + 5, 0)
la lista
NU-LLIF(input,value) input or NULO retorna NULO si NULLIF(c1, ’N/A’)
input = value
CASE WHEN expr expr retorna la CASE WHEN c1 =
THEN expr [...] expresión para la 1 THEN ’match’
ELSE expr END primera claúsula ELSE ’no match’
verdadera END

FUNCIONES MATEMÁTICAS

Funciones Retorna Descripción Ejemplo


dexp(foat8) fooat8 redimensiona dexp(2.0)
al exponente
especificado
float8 redimensiona dpow(2.0, 16.0)
un numero
al exponente
especificado
float(int) float8 convierte un float(2)
entero a punto
float4(int) foat4 convierte un foat4(2)
entero a punto
integer(float) int convierte un integer(2.0)
punto flotante a punto
FUNCIONES STRING

SQL92 define funciones de texto con sintaxis específica. Algunas son implementadas usando otras
funciones Postgres Los tipos de Texto soportados para SQL92 son char, varchar, y text.

Funciones Retorna Descripción Ejemplo


char_ int4 longitud del texto char_
charac- ter_ int4 longitud del texto char_
lower(string) string convierte el texto lower(’TOM’)
octet_ int4 almacena el octet_ octet_
position(string in int4 localiza la position (’o’) in
substring(string string extrae un substring (’Tom’)
string oth] borra caracteres trim(both ’x’ )from
upper(text) text convierte un texto upper(’tom’)

La mayoría de funciones de texto están disponibles para tipos text, varchar() y char().Algunas son
usadas internamente para implementar las funciones de texto SQL92 descritas arriba.

Funciones Retorna Descripción Ejemplo


char(text) Char convierte un texto a char(’text string’)
tipo char
char(varchar) char convierte un varchar a (varchar
tipo char ’varchar string’)
initcap(text) text primera letra de cada (’thomas’)
palabra a initcap
pad(text,int,text) text relleno de caracteres (’hi’,4,’??’)
por lpad
ltrim(text,text) text recorte de caracteres
textpos(text,text) text localiza un subtexto position(’high’,’ig’)
rpad(text,int,text) text relleno de caracteres (’hi’,4,’x’)
por rpad
rtrim(text,text) text recorte de caracteres
text extrae el subtexto substr(’hi there’,3,5)
especificado
text(char) text convierte char a tipo text(’char string’)
text
text(varchar) text convierte varchar a (varchar
tipo text ’varchar string’)
translate(text,from,to) text convierte character a (’12345’)
string translate
varchar(char) varchar convierte char a tipo varchar (’char
varchar string’)
varchar(text) varchar convierte text a tipo varchar (’text
varchar string’)

La mayoría de funciones explícitamente defI8nidas para texto trabajarán para argumentos char () y
varchar().

FUNCIONES DE FECHA/HORA

Las funciones de Fecha/Hora provee un poderoso conjunto de herramientas para manipular varios
tipos Date/Time.

Funciones Retorno Descripción Ejemplo


abstime convierte a abstime
timespan preserva meses y age (’now’,’1957-
) años 06-
13’::datetime)
datetime(date) datetime convierte date datetime(’1998-
a datetime 02-
24’::datetime,
da- te_ float8 porción de fecha da- te_
part (’dow’,’now’::
datetime
da- te_ float8 porción de hora date_
part(’hour’,’4
hrs 3
mins’::timespan)
da- te_ datetime fecha truncada da- te_
trunc(’month’,’now
isfnite(abstime) bool un tiempo finito? isfni-
isfnite(datetime) bool una hora finita? isfni-
isfnite(timespan) bool una hora finita? isfnite(’4
reltime(timespan) reltime convierte a reltime(’4
reltime
timespan(reltime) timespan convierte a timespan(’4
timespan

Para las funciones date_part and date_trunc, los argumentos pueden ser ‘year’, ‘month’, ‘day’, ‘hour’,
‘minute’, y ‘second’, así como las mas especializadas cantidades ‘decade’, ‘century’, ‘millenium’,
‘millisecond’, y ‘microsecond’. date_part permite ‘dow’ para retornar el día de la semana ‘epoch’ para
retornar los segundos desde 1970 (para datetime) o ’epoch’ para retornar el total de segundos
transcurridos (para timespan).
FUNCIONES DE FORMATO

Las funciones de formato proveen un poderoso conjunto de herramientas para convertir varios
datetypes (date/time, int, float, numeric) a texto formateado y convertir de texto formateado a su
datetypes original.

Funciones Retorno Descripción Ejemplo


to_char(datetime, text convierte datetime a to_
text) string
to_char(timestamp, text convierte timestamp a to_char( now(),
to_char ’HH12:MI:SS’)
to_char(int, text) text convierte int4/int8 a to_char(125, ’999’)
string
to_char(float, text convierte foat4/ to_char(125.8,
text) float8 a string ’999D9’)
to_ char(numeric, text convierte to_char(-125.8,
numeric a string ’999D99S’)
to_datetime(text, datetime convierte string to_datetime(’05
text) a datetime Dec 2000 13’, DD
Mon)
to_date(text, date convierte string to_date(’05 Dec
text) a date 2000’, ’DD Mon)
to_ date convierte string to_timestamp(’05
timestamp(text, a timestamp Dec 2000’, ’DD
text) Mon)
to_number(text, numeric convierte string a
text) numeric

Para todas las funciones de formato, el segundo argumento es format-picture.

Format-picture Descripción
HH hora del día(01-12)
HH12 hora del día(01-12)
MI minuto (00-59)
SS segundos (00-59)
SSSS segundos pasados la medianoche(0-
86399)
Y,YYY año(4 o mas dígitos) con coma
YYYY año(4 o mas dígitos)
YYY últimos 3 dígitos del año
YY últimos 2 dígitos del año
Y último dígito del año
MONTH nombre completo del mes(9-letras) -
todos los caracteres en mayúsculas
Month nombre completo del mes(9-
letras) - el primer carácter en mayúsculas
month nombre completo del mes(9-letras) -
todos los caracteres en minúsculas
MON nombre abreviado del mes(3-letras)
-todos los caracteres en mayúsculas
Mon nombre abreviado del mes(3-letras)
- el primer carácter en mayúsculas
mon nombre abreviado del mes(3-letras)
- todos los caracteres en minúsculas
MM mes (01-12)
DAY nombre completo del día(9-letters) -
todos los caracteres en mayúsculas
Day nombre completo del día(9-letters) -
el primer carácter en mayúsculas
day nombre completo del día(9-letters) -
todos los caracteres en minúsculas
DY nombre abreviado del día(3-letters)
- todos los caracteres en mayúsculas
Dy nombre abreviado del día(3-letters)
- el primer carácter en mayúsculas
dy nombre abreviado del día(3-letters)
- todos los caracteres en minúsculas
DDD día del año(001-366)
DD día del mes(01-31)
D día de la semana(1-7; SUN=1)
W semana del mes
WW número de la semana en el año
CC centuria (2-digits)
J día juliano (días desde Enero 1, 4712
BC)
Q Quarter
RM mes en numeral romano(I-XII;
I=ENE)
JOINS
JOINS (CRUCES)

El siguiente ejemplo muestra como las joins (cruces) se realizan en SQL.

Para cruzar tres tablas PRODUCTOS, PROVEEDORES y DETALLE ORDENES a través de sus
atributos comunes, formularemos la siguiente instrucción:

SELECT pr.nombreprov, p.descripcion, d.cantidad


FROM proveedores pr, productos p, detalle_ordenes d
WHERE p.productoid = d.productoid AND pr.proveedorid=p.proveedorid:;

En la clausula FROM hemos introducido un alias al nombre para cada relación porque hay atributos
con nombre común en las relaciones. Ahora podemos distinguir entre los atributos con nombre
común simplificando la adicción de un prefijo al nombre del atributo con el nombre del alias seguido
de un punto.

La join se calcula de la misma forma, tal como se muestra en Una Inner Join (Una Join Interna).
Primero el producto cartesiano PRODUCTOS x PROVEEDORES x DETALLE ORDENES.
Ahora seleccionamos únicamente aquellas tuplas que satisfagan las condiciones dadas en la
clausula WHERE (es decir, los atributos con nombre común deben ser iguales).

OPERADORES AGREGADOS

SQL proporciona operadores agregados (como son AVG, COUNT, SUM, MIN, MAX) que toman el
nombre de un atributo como argumento. El valor del operador agregado se calcula sobre todos los
valores de la columna especificada en la tabla completa. Si se especifican grupos en la consulta, el
cálculo se hace sólo sobre los valores de cada grupo (vean la siguiente sección).

Ejemplo:

Si queremos conocer el coste promedio de todos los artículos de la tabla PART, utilizaremos la
siguiente consulta:

SELECT AVG(preciounit) AS “Precio promedio”


FROM productos;

Si queremos conocer cuántos artículos se recogen en la tabla PART, utilizaremos la instrucción:

SELECT COUNT(productoid)
FROM productos;
AGREGACIÓN POR GRUPOS

SQL nos permite particionar las tuplas de una tabla en grupos. En estas condiciones, los operadores
agregados descritos antes pueden aplicarse a los grupos (es decir, el valor del operador agregado
no se calculan sobre todos los valores de la columna especificada, sino sobre todos los valores de
un grupo.
El operador agregado se calcula individualmente para cada grupo).

Ejemplo:

Si queremos conocer cuántos artículos han sido vendidos por cada proveedor formularemos la
consulta:

SELECT pr.proveedorid, pr.nombreprov, COUNT (p.productoid)


FROM proveedores pr, productos p
WHERE pr.proveedorid= p.proveedorid
GROUP BY pr.proveedorid, pr.nombreprov;

HAVING

La clausula HAVING trabaja de forma muy parecida a la clausula WHERE, y se utiliza para
considerar sólo aquellos grupos que satisfagan la cualificación dada en la misma. Las expresiones
permitidas en la clausula HAVING deben involucrar funcionen agregadas.
Cada expresión que utilice sólo atributos planos deberá recogerse en la clausula WHERE.

Por otro lado, toda expresión que involucre funciones agregadas debe aparecer en la clausula
HAVING.

Ejemplo

Si queremos solamente los proveedores que venden más de un artículo, utilizaremos la consulta:

SELECT pr.proveedorid, pr.nombreprov, COUNT(p.productoid)


FROM proveedores pr, productos p
WHERE pr.proveedorid= p.proveedorid
GROUP BY pr.proveedorid, pr.nombreprov
HAVING COUNT(p.productoid) >1;
SUBCONSULTAS
SUBCONSULTAS

En las clausulas WHERE y HAVING se permite el uso de subconsultas (subselects) en cualquier


lugar donde se espere un valor. En este caso, el valor debe derivar de la evaluación previa de la
subconsulta.

 El uso de subconsultas amplía el poder expresivo de SQL.

Ejemplo:

Si queremos conocer los artículos que tienen mayor precio que el producto llamado ’Tornillos’,
utilizaremos la consulta:

SELECT * FROM productos


WHERE preciounit > (SELECT preciounit FROM productos
WHERE descripcion =’BOTON PARA ASADO’);

Cuando revisamos la consulta anterior, podemos ver la palabra clave SELECT dos veces. La
primera al principio de la consulta - a la que nos referiremos como la SELECT externa - y la segunda
en la clausula WHERE, donde empieza una consulta anidada - nos referiremos a ella como la
SELECT interna.

Para cada tupla de la SELECT externa, la SELECT interna deberá ser evaluada. Tras cada
evaluación, conoceremos el precio de la tupla llamada ‘BOTON PARA ASADO’, y podremos
chequear si el precio de la tupla actual es mayor.

Si queremos conocer todos los proveedores que no venden ningún producto (por ejemplo, para
poderlos eliminar de la base de datos), utilizaremos:

SELECT * FROM proveedores p


WHERE NOT EXISTS
(SELECT * FROM productos pr WHERE pr.proveedorid =
p.proveedorid);

UNIÓN, INTERSECCIÓN, EXCEPCIÓN

Estas operaciones calculan la unión, la intersección y la diferencia de la teoría de conjuntos de las


tuplas derivadas de dos subconsultas.

Ejemplo: Union, Intersect, Except

 La siguiente consulta es un ejemplo de UNION:


SELECT p.nombreprov, p.contacto
FROM proveedores p
WHERE p.nombreprov= ‘TONY’ UNION
SELECT p.nombreprov, p.contacto
FROM proveedores p
WHERE p.nombreprov= ‘JURIS’

 Aquí se tiene un ejemplo para INTERSECT:

SELECT p.nombreprov, p.contacto


FROM proveedores p
WHERE p.nombreprov= ‘TONY’ INTERSECT
SELECT p.nombreprov, p.contacto
FROM proveedores p
WHERE p.nombreprov= ‘JURIS’

 Finalmente, un ejemplo de EXCEPT:

SELECT p.nombreprov, p.contacto


FROM proveedores p
WHERE p.nombreprov= ‘TONY’ EXCEPT
SELECT p.nombreprov, p.contacto
FROM proveedores p
WHERE p.nombreprov= ‘JURIS’
TRANSACCIONES
TRANSACCIONES

Las transacciones son un concepto fundamental en todos los sistemas de base de datos, el punto
esencial de una transacción es que engloba múltiples operaciones en un solo paso.

En PostgreSQL las transacciones se configuran simplemente encerrando en un bloque las


operaciones que se desean incluir en la misma, el bloque debe comenzar y terminar con los
comandos BEGIN y COMMIT.

BEGIN: Comienza una transacción en modo encadenado


BEGIN [ WORK | TRANSACTION ]

Para comenzar una transacción de usuario:


BEGIN WORK;

Entrada: WORK, TRANSACTION


Palabras clave opcionales. No tienen efecto.

Salida: BEGIN
Esto significa que una nueva transacción ha sido comenzada.

NOTICE: BEGIN: already a transaction in progress

Esto indica que una transacción ya está en progreso. La transacción en curso no se ve afectada.

Descripción

Por defecto, PostgreSQL ejecuta las transacciones en modo no encadenado (también conocido
como “autocommit” en otros sistemas de base de datos). En otras palabras, cada estado de usuario
es ejecutado en su propia transacción y un commit se ejecuta implícitamente al final del estatuto (si
la ejecución fue exitosa, de otro modo se ejecuta un rollback). BEGIN inicia una transacción de
usuario en modo encadenado, todos los estados de usuarios después de un comando BEGIN se
ejecutaran en una transacción única hasta un explicito COMMIT, ROLLBACK, o aborte la ejecución.

Los estados en modo encadenado se ejecutan mucho más rápido, porque la transacción
start/commit requiere una actividad significativa de CPU y de disco. La ejecución de múltiples
estados dentro de una transacción también es requerida para la consistencia cuando se cambian
muchas tablas relacionadas.

El nivel de aislamiento por defecto de las transacciones en PostgreSQL es READ COMMITTED,


donde las consultas dentro de la transacción solo tienen en cuenta los cambios consolidados antes
de la ejecución de la consulta. Así pues, debes utilizar SET TRANSACTION ISOLATION LEVEL
SERIALIZABLE justo después de BEGIN si necesitas aislamiento de transacciones más riguroso.

Las consultas del tipo SERIALIZABLE solo tendrán en cuenta los cambios consolidados antes de
que la transacción entera comience (realmente, antes de la ejecución del primer estado DML en una
transacción serializable).
Si la transacción está consolidada, PostgreSQL asegurara que todas las actualizaciones sean
hechas o si no que ninguna de ellas lo sea. Las transacciones tienen la propiedad estándar ACID
(atómica, consistente, aislada y durable).

COMMIT

Realiza la transacción actual


COMMIT [ WORK | TRANSACTION ]

Para hacer todos los cambios permanentes:


COMMIT WORK;

Entrada: WORK, TRANSACTION


Palabra clave opcional. No tiene efecto.

Salida: COMMIT
Mensaje devuelto si la transacción se realiza con éxito.

NOTICE: COMMIT: no transaction in progress


Si no hay transacciones en progreso.

Descripción

COMMIT realiza la transacción actual. Todos los cambios realizados por la transacción son visibles a
las otras transacciones, y se garantiza que se conservan si se produce una caída de la máquina.

ROLLBACK

Interrumpe la transacción en curso


ROLLBACK [ WORK | TRANSACTION ]

Para cancelar todos los cambios:


ROLLBACK WORK;

Entrada: Ninguna.

Salida: ABORT
Mensaje devuelto si la operación es exitosa.

NOTICE: ROLLBACK: no transaction in progress


Si no hay transacciones en progreso actualmente.

Descripción

ROLLBACK deshace la transacción actual y provoca que todas las modificaciones originadas por la
misma sean descartadas.

ABORT es un sinónimo de ROLLBACK.

Estructura de una transacción:

BEGIN;
UPDATE cuentas SET balance = balance – 100 WHERE nombre = ‘Alice’;

COMMIT;
Al momento que se le pasa a PostgreSQL la clausula COMMIT es cuando se escribe en base de
datos las actualizaciones u operación que se desea hacer en la misma, si en algún momento no
queremos hacer COMMIT de alguna operación (quizás se nota que la cuenta de Alice da un balance
negativo) entonces se puede utilizar la clausula ROLLBACK y todas las actualizaciones dentro de la
transacción se cancelaran.
Si no se desea hacer un rollback completo de la transacción, entonces se pueden definir marcadores
(savepoints) hasta los cuales se desea que se regrese en la transacción,

Ejemplo:

BEGIN;
UPDATE cuentas SET balance = balance – 100 WHERE nombre = ‘Alice’;
SAVEPOINT marcador1;
UPDATE cuentas SET balance = balance + 100 WHERE nombre = ‘Bob’;
— se desea descartar la actualizacion para Bob y en vez hacerla para Wally —
ROLLBACK TO marcador1;
UPDATE cuentas SET balance = balance + 100 WHERE nombre = ‘Wally’;
COMMIT;

En el ejemplo anterior se vio el uso de Marcadores y Rollbacks, en este caso lo que paso es que se
realizo una actualización sobre la cuenta de Bob, pero a ultima instancia se decide que el dinero no
se le va a abonar a Bob sino a Wally, entonces se realiza un rollback hasta el marcador llamado
marcador1 y se pasa a hacer la actualización en la cuenta de Wally
VISTAS
Y
REGLAS
VISTAS Y REGLAS

VISTAS

Se puede ver una vista como una tabla virtual, es decir, una tabla que no existe físicamente en la
base de datos, pero aparece al usuario como si existiese. Por contra, cuando hablamos de una tabla
base, hay realmente un equivalente almacenado para cada fila en la tabla en algún sitio del
almacenamiento físico.

Las vistas no tienen datos almacenados propios, distinguibles y físicamente almacenados. En su


lugar, el sistema almacena la definición de la vista (es decir, las reglas para acceder a las tablas
base físicamente almacenadas para materializar la vista) en algún lugar de los catálogos del sistema
(vea System Catalogs).

En SQL se utiliza el comando CREATE VIEW para definir una vista.

La Sintaxis es:

CREATE VIEW view_name


AS select_stmt

Donde select_stmt es una instrucción select válida, como se definió en Select.

Nótese que select_stmt no se ejecuta cuando se crea la vista. Simplemente se almacena en los
catálogos del sistema y se ejecuta cada vez que se realiza una consulta contra la vista.

SELECT *
FROM categorias
WHERE nombrecat = ‘CARNICOS’

REGLAS

CREATE RULE - definen una nueva regla de reescritura

Sintaxis:

CREATE [ OR REPLACE ] RULE nombre AS ON evento


TO tabla [ WHERE condicion ]
DO [ ALSO | INSTEAD ] { NOTHING | commando | ( commando ; commando ...) }
Descripción

CREATE RULE define una nueva norma se aplica a una tabla o vista especificada. CREATE OR
REPLACE pronunciarse creará una nueva regla, o cambiará una regla existente del mismo nombre
para la misma tabla.

El sistema de reglas PostgreSQL permite definir una acción alternativa para llevar a cabo en las
inserciones, actualizaciones o supresiones en las tablas de bases de datos.

En términos generales, una regla causas comandos adicionales que se ejecutan cuando una orden
dada en una tabla dada es ejecutada. Las reglas se utilizan también para implementar las vistas de
tabla.

Es importante darse cuenta de que una norma es en realidad un mecanismo de transformación de


comandos, o macro de comandos. La transformación ocurre antes que la ejecución de los comandos
se inicie.

Parámetros

 name: El nombre de una norma para crear. Esta debe ser distinta del nombre de cualquier
otra norma de la misma tabla. Múltiples reglas sobre la misma mesa y mismo tipo de evento
se aplican en el orden del nombre alfabético.
 event: El evento es uno de SELECT, INSERT, UPDATE o DELETE.
 table: El nombre (opcional esquema cualificada) de la tabla o vista se aplica la regla.
 condition: Cualquier expresión condicional SQL (volviendo boolean. La expresión de
condición no puede referirse a las tablas, salvo NEW y OLD, y no puede contener funciones
de agregado.
 INSTEAD: indica que los comandos deben ser ejecutados en lugar del comando original.
 ALSO: indica que los comandos deben ser ejecutados, además de la orden original.
 command: El comando o comandos que componen la acción de la regla. Comandos válidos
son SELECT, INSERT, UPDATE, DELETE o NOTIFY.

Dentro de condición y de comandos, los nombres de tabla especial NEW y OLD pueden ser usados
para referirse a los valores en la tabla referenciada.

NUEVO es válido en ON INSERT y UPDATE ON normas que se refieren a la nueva fila a insertar o
actualizar. OLD es válido en ON y ON UPDATE DELETE normas para hacer referencia a la fila
existente se actualiza o eliminado.

Es muy importante tener cuidado para evitar reglas circulares.


Ejemplos:

CREATE OR REPLACE RULE regla2 AS


ON INSERT TO empleados
WHERE empleadoid>3
DO NOTHING;

CREATE OR REPLACE RULE regla3 AS


ON INSERT TO empleados
WHERE apellido like ‘NOBOA’
DO NOTHING
PROCEDIMIENTOS
ALMACENADOS
PROCEDIMIENTOS ALMACENADOS

Un procedimiento almacenado se puede definir como un programa, procedimiento ó función, el cual


está almacenado en la base de datos y listo para ser usado.

Existen dos ventajas evidentes al utilizar procedimientos almacenados en nuestro sistema:

 La ejecución del procedimiento ocurre en el servidor de bases de datos. Esto probablemente


aumentará el rendimiento de nuestra aplicación al no tenerse que mandar datos entre el
cliente y el servidor, y no tener que procesar resultados intermedios en el cliente para
obtener el resultado final.

 Al tener la lógica de la aplicación implementada en la base de datos no tendremos que


implementarla en los clientes, con el consiguiente ahorro de líneas de código redundante y
complejidad.

Podemos definir e instalar un procedimiento en PL/pgSQL de la siguiente manera:

CREATE [ OR REPLACE ] FUNCTION


nombre_funcion([ [ argmodo ] [ argnombre ] argtipo [, ...] ])
RETURNS tipo AS $$

[ DECLARE ]
[ declaraciones de variables ]
BEGIN
codigo
END;
$$ LANGUAGE plpgsql
| IMMUTABLE | STABLE | VOLATILE
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
| [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
| COST execution_cost
| ROWS result_rows
| SET confguration_parameter { TO value | = value | FROM CURRENT }

A continuación vamos a ver algunas de las opciones y valores más importantes.

 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
 declaraciones de variables: Las declaraciones de variables se pueden realizar de la
siguiente manera ($n = orden de declaración del argumento.):

nombre_variable ALIAS FOR $n;


nombre_variable [ CONSTANT ] tipo [ NOT NULL ] [ { DEFAULT | := } expresion ];

IMMUTABLE | STABLE | VOLATILE:

 IMMUTABLE: Indica que la función 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 función 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 podría cambiar entre sentencias SQL.

 VOLATILE: Indica que la función puede devolver diferentes valores, incluso dentro de una
consulta individual de una tabla (valor por defecto)

 CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT:

CALLED ON NULL INPUT: Indica que la función se ejecutará aunque algunos de los argumentos
sean NULL. El usuario tiene la responsabilidad de comprobar si algún argumento es NULL cuando
sea necesario tener esto en cuenta. (Valor por defecto)

RETURNS NULL ON NULL INPUT / STRICT: Indican que la función no se ejecutará y devolverá el
valor NULL si alguno de los argumentos es NULL.

 SECURITY INVOKER | SECURITY DEFINER:

SECURITY INVOKER: Indica que la función se ejecutará con los privilegios del usuario que la
ejecuta (valor por defecto).

SECURITY DEFINER: Indica que la función se ejecutará con los privilegios del usuario que la creo.

Ejemplos:

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.

CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql;


A continuación creamos nuestro primer procedimiento. (Podemos copiar y pegar en el cliente psql,
escribirlo a mano ó usar el editor interno en psql (\e)):

CREATE OR REPLACE FUNCTION ejemplo() RETURNS integer AS $$


BEGIN
RETURN 104;
END;
$$ LANGUAGE plpgsql;

 Ahora definimos la función con un argumento:

CREATE OR REPLACE FUNCTION ejemplo(integer) RETURNS integer AS $$


BEGIN
RETURN $1;
END;
$$ LANGUAGE plpgsql;

 Este procedimiento se podría haber escrito también de las siguientes maneras:

CREATE OR REPLACE FUNCTION ejemplo(numero integer) RETURNS integer AS $$


BEGIN
RETURN numero;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION ejemplo(integer) RETURNS integer AS $$
DECLARE
numero ALIAS FOR $1;
BEGIN
RETURN numero;
END;
$$ LANGUAGE plpgsql;

 Vamos a empezar a complicar un poco las cosas usando dos argumentos y defniendo
algunas variables:

CREATE OR REPLACE FUNCTION ejemplo(integer , integer) RETURNS integer AS $$


DECLARE
numero1 ALIAS FOR $1;
numero2 ALIAS FOR $2;

constante CONSTANT integer := 100;


resultado integer;
BEGIN
resultado := (numero1 * numero2) + constante;

RETURN resultado;
END;
$$ LANGUAGE plpgsql;

 A continuación vamos a usar una sentencia IF ... THEN en nuestra función:

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;
TRIGGERS
TRIGGER

Las diversas funciones proporcionan grandes ventajas al simplificar acciones en la base de datos.
Pero estas acciones requieren la intervención de una persona encargada de ejecutar dichas
funciones cuando se requiera de su actuación.

Los Triggers al contrario son funciones que se ejecutan de forma automática en respuesta a ciertos
eventos que ocurren en la base de datos.

Un trigger es un tipo especial de procedimiento almacenado que es disparado cuando se intenta


modificar los datos que protegen. Un procedimiento almacenado es invocado por el usuario mientras
que un trigger lo es por el SQL.

CREATE TRIGGER crea un nuevo trigger. El trigger se asociará con la tabla especificada y
ejecutará la función especificada function_name cuando ocurra cierto evento.
Los triggers pueden ser definidos a ejecutarse antes o después de cualquier operación INSERT,
UPDATE O DELETE, una vez por fila modificada o por una declaración del SQL.

La función trigger debe ser definida antes de que el propio trigger se cree. Si el trigger se ejecuta
antes del evento, el trigger puede saltar la operación de la fila actual, o cambiar la fila a ser insertada
(solamente para operaciones INSERT y UPDATE). Si el trigger se ejecuta después del evento, todo
cambia, incluyendo los efectos de otros triggers, son visibles al trigger.

Un trigger que es marcado FOR EACH ROW (row-level) es llamado una vez por cada fila que
modifica la operación. Por ejemplo, una operación DELETE que afecta a 10 filas causaría cualquier
ON DELETE triggers en la relación designada a ser llamada 10 veces independientemente, una vez
por cada fila borrada.

En contraste, un trigger que es marcado FOR EACH STATEMENT (statement-level) sólo se ejecuta
una vez para cada operación dada sin tener en cuenta cuantas flas modifica (en particular, una
operación que modifica cero filas todavía producirá la ejecución de cualquier FOR EACH
STATEMENT trigger).

Adicionalmente:
 Los triggers pueden ser definidos para disparar a un TRUNCATE, aunque solo FOR EACH
STATEMENT.

También, una definición de trigger puede especificar una condición booleana WHEN, la cual se
probará para ver si el trigger se disparará o no. En los triggers de niveles de flas la condición WHEN
puede examinar los valores antiguos y/o nuevos de la columna de la fila.
Los triggers de nivel de sentencias pueden también tener condiciones WHEN, aunque el rasgo no
es tan útil para ellos ya que la condición no puede referirse a cualquier valor en la tabla.

Si se definen múltiples triggers del mismo tipo para el mismo evento, pueden ser disparados
alfabéticamente de acuerdo al nombre.

SELECT no modifica flas por lo tanto no se pueden crear triggers SELECT. Las reglas y vistas son
más apropiadas en estos casos.

Para crear un trigger en una tabla, el usuario debe tener el privilegio de crear triggers para esa tabla.

 Para eliminar un trigger se debe utilizar la clausula DROP TRIGGER.

Sintáxis:

CREATE TRIGGER name { BEFORE | AFTER } { event [ OR ... ] }

ON table [ FOR [ EACH ] { ROW | STATEMENT } ]

[ WHEN ( condition ) ]

EXECUTE PROCEDURE function_name ( arguments )

Donde:

 name: Nombre del Nuevo trigger. Este debe ser distinto de cualquier nombre de otro trigger
en la misma tabla.
 BEFORE, AFTER: Determina si la función es llamada antes o después de un evento.
 event: Una de INSERT, UPDATE, DELETE o TRUNCATE; este especifica el evento que
ocurrirá cuando el trigger dispare. Se pueden utilizar varios eventos utilizando OR.

Para los triggers UPDATE, es posible especificar una lista de columnas utilizando eta sintaxis:

UPDATE OF column_name1 [, column_name2 ... ]

El trigger disparará solamente si al menos una de las columnas listadas es mencionada como
designada a actualizar.

 table: Nombre de la tabla para la cual es el trigger.


 FOR EACH ROW, FOR EACH STATEMENT: Especifica si el procedimiento del trigger será
disparado una vez para todas las flas afectadas por el evento, o solo una vez por cada
declaración SQL. Si no se especifica, el valor predeterminado es FOR EACH STATEMENT.
 condition: Una expresión booleana que determina si la función del trigger se ejecutará
realmente. Si WHEN es especificado, la función solo será llamada si la condición retorna
verdadero.
 function_name: Función de usuario declarada para no tomar ningún valor y retornar el tipo
de trigger, la cual es ejecutada cuando el trigger dispara.
 arguments: Una lista opcional de argumentos separados por coma para ser proporcionada
a la función cuando el trigger es ejecutado. Los argumentos son cadenas de caracteres
constantes. Simples nombres o constantes numéricas pueden ser utilizados también pero
pueden ser convertidos en cadenas de caracteres.

Ejemplos:

Ejecutar la función check_account_update siempre que una fila de la tabla accounts sea actualizada:

CREATE TRIGGER trigger_actualizacion


BEFORE UPDATE ON PROVEEDORES
FOR EACH ROW
EXECUTE PROCEDURE check_proveedores_update();

También podría gustarte