Documentos de Académico
Documentos de Profesional
Documentos de Cultura
5.-PLSQL PostGre
5.-PLSQL PostGre
PG/PLSQL
Miguel ngel Manso ETSI en Topografa, Geodesia y Cartografa - UPM
ndice
Estructura PL/PGSQL Declaraciones, Alias para parmetros en funciones Datos de tipo tabla, Type & RowType Sentencias, estructuras de control Reporte de errores, cursores Triggers
14/12/2010
Estructura PL/PGSQL
CREATE OR REPLACE PROCEDURE [esquema].nombre-procedimiento(nombre-parmetro {IN, OUT, IN OUT} tipo de dato, ..) {IS, AS} Declaracin de variables; Declaracin de constantes; Declaracin de cursores; BEGIN Cuerpo del subprograma PL/SQL; EXCEPTION Bloque de excepciones PL/SQL; END; CREATE OR REPLACE FUNCTION [esquema].nombre-funcion(nombre-parmetro {IN, OUT, IN OUT} tipo-dedato, ..) RETURN tipo-de-dato {IS, AS} Declaracin de variables; Declaracin de constantes; Declaracin de cursores; BEGIN Cuerpo del subprograma PL/SQL; EXCEPTION Bloque de excepciones PL/SQL; END;
Declaraciones
Sintaxis general:
name [ CONSTANT ] type [ NOT NULL ] [ { DEFAULT | := } expression ];
Ejemplos:
user_id integer; quantity numeric(5); url varchar; myrow tablename%ROWTYPE; myfield tablename.columnname%TYPE; arow RECORD; quantity INTEGER DEFAULT 32; url varchar := http://mysite.com; user_id CONSTANT INTEGER := 10;
14/12/2010
BEGIN
SELECT * INTO use_t FROM table2name WHERE ... ; RETURN in_t.f1 || use_t.f3 || in_t.f5 || use_t.f7;
14/12/2010
Para crear una variable de tipo registro asociado a las columnas de una tabla
users_rec users%ROWTYPE;
Sentencias
Asignacin: <Variable> := <valor>;
user_id := 20; tax := subtotal * 0.06;
14/12/2010
Sentencias
No hacer nada: Null; Ejecucin dinmica: EXECUTE texto-comando;
EXECUTE UPDATE tabla SET || quote_ident(nombreCampo) || = || quote_literal(NuevoValor) || WHERE ...;
Estructuras de control
Retorno de resultados:
Return expresin;
Condicionales:
IF ... THEN IF ... THEN ... ELSE IF ... THEN ... ELSE IF IF ... THEN ... ELSIF ... THEN ... ELSE IF ... THEN ... ELSEIF ... THEN ... ELSE
14/12/2010
Bucles
Bucles simples:
[<<label>>] LOOP
sentencias
EXIT [ label ] [ WHEN expresion ];
END LOOP;
Ejemplos: LOOP -- algunos clculos IF count > 0 THEN EXIT; -- exit loop END IF; END LOOP; LOOP -- otros clculos EXIT WHEN count > 0; END LOOP;
Bucle While
While
[<<label>>] WHILE expresin LOOP sentencias END LOOP;
Ejemplos
WHILE amount_owed > 0 AND gift_certificate_balance > 0 LOOP -- algunos clculos END LOOP; WHILE NOT expresin_booleana LOOP -- algunos clculos END LOOP;
14/12/2010
Bucle For
For [<<label>>] FOR nombre IN [ REVERSE ] expresin .. expresin LOOP sentencias END LOOP; Ejemplos
FOR i IN 1..10 LOOP -- algunas expresiones RAISE NOTICE i is %,i; END LOOP; FOR i IN REVERSE 10..1 LOOP -- algunas expresiones END LOOP;
Ejemplo
CREATE FUNCTION cs_refresh_mviews () RETURNS INTEGER AS DECLARE mviews RECORD; BEGIN PERFORM cs_log(Actualizando las vistas...); FOR mviews IN SELECT * FROM vista_cs ORDER BY sort_key LOOP -- Ahora "mviews" contiene un registro de vista_cs PERFORM cs_log(Actualizando las vistas || quote_ident(mviews.mv_name) .. END LOOP; RETURN 1; END; LANGUAGE plpgsql;
14/12/2010
Reportar errores
RAISE level format [, variable [...]]; Ejemplos:
RAISE NOTICE Invocando cs_create_job(%),v_job_id; RAISE EXCEPTION No existe el ID --> %,user_id;
Cursores
Declaracin:
nombre CURSOR [ ( argumentos ) ] FOR|IS consulta ;
Ejemplos:
curs1 refcursor; --Es un tipo de dato genrico para cursores curs2 CURSOR FOR SELECT * FROM tenk1; curs3 CURSOR (key integer) IS SELECT * FROM tenk1 WHERE unique1 = key;
Ejemplos:
OPEN curs1 FOR SELECT * FROM foo WHERE key = mykey; OPEN curs1 FOR EXECUTE 'SELECT * FROM ' || quote_ident($1);
14/12/2010
Cursores
Usar cursores:
FETCH cursor INTO target;
Cerrar cursores:
CLOSE cursor;
Retornar cursores:
CREATE TABLE prueba (columna text); INSERT INTO prueba VALUES (123); CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS BEGIN OPEN $1 FOR SELECT columna FROM prueba; RETURN $1; END; LANGUAGE plpgsql; BEGIN; SELECT reffunc(funccursor ); FETCH ALL IN funccursor; COMMIT;
Triggers
CREATE TRIGGER --- argumentos va TG_ARGV
Posibles argumentos:
NEW OLD TG_NAME TG_WHEN TG_LEVEL TG_OP TG_RELID TG_RELNAME TG_NARGS TG_ARGV[] variable con los nuevos datos Variable con el dato antiguo Nombre del trigger Cundo se dispara AFTER, BEFORE Nivel al que afecta: fila, sentencia Operacin que dispara (INSERT, UPDATE; DELETE) ID del objecto de la tabla que dispara el trigger nombre de la tabla que dispara el trigger n de argumentos
14/12/2010
Ejemplo trigger
1 CREATE TABLE numeros( numero bigint NOT NULL, cuadrado bigint, cubo bigint, raiz2 real, raiz3 real, PRIMARY KEY (numero) ); 2 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 NULL; END; $rellenar_datos$ LANGUAGE plpgsql; 3 CREATE TRIGGER rellena_datos BEFORE INSERT OR UPDATE ON numeros FOR EACH ROW EXECUTE PROCEDURE rellenar_datos();
10
14/12/2010
Ejemplo trigger
CREATE TABLE emp ( empname text, salary integer, last_date timestamp, last_user text ); CREATE FUNCTION emp_stamp () RETURNS TRIGGER AS BEGIN IF NEW.empname ISNULL THEN -- Comprueba que se proporcionan: empname y salary RAISE EXCEPTION empname no puede ser NULL; END IF; IF NEW.salary ISNULL THEN RAISE EXCEPTION El empleado % no puede tener salario NULL, NEW.empname; END IF; IF NEW.salary < 0 THEN -- El sueldo no puede ser negativo! RAISE EXCEPTION El empleado % no puede tener salario negativo, NEW.empname; END IF; NEW.last_date := now ; -- Se almacena quin y cundo se cambiaron los datos NEW.last_user := current_user; RETURN NEW; END; LANGUAGE plpgsql; CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
Referencias
http://plsql-tutorial.com/index.htm http://www.postgresql-es.org/node/297 Triggers: http://www.postgresql-es.org/node/301
11