Sei sulla pagina 1di 11

14/12/2010

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;

Registro Tipo col. Registro

14/12/2010

Alias para parmetros de funciones


name ALIAS FOR $n; Ejemplo:
CREATE FUNCTION sales_tax(REAL) RETURNS REAL AS DECLARE subtotal ALIAS FOR $1; BEGIN return subtotal * 0.06; END; LANGUAGE plpgsql; CREATE FUNCTION instr(VARCHAR, INTEGER) RETURNS INTEGER AS DECLARE v_string ALIAS FOR $1; index ALIAS FOR $2; BEGIN

Datos de tipo Tabla


name tablename%ROWTYPE; -- Variable de tipo complejo (registro) -- Se usa name.fieldName CREATE FUNCTION use_two_tables(tablename) RETURNS TEXT AS DECLARE
in_t ALIAS FOR $1; use_t table2name%ROWTYPE;

BEGIN
SELECT * INTO use_t FROM table2name WHERE ... ; RETURN in_t.f1 || use_t.f3 || in_t.f5 || use_t.f7;

END; LANGUAGE plpgsql;

14/12/2010

Type & RowType


Conocer el tipo de dato de una variable Type
user_id users.user_id%TYPE;

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;

SELECT INTO target select_expressions FROM ...;


SELECT INTO Result * FROM EMP WHERE empname = myname; IF NOT FOUND THEN RAISE EXCEPTION El empleado % no existe , myname; END IF;

Ejecucin sin resultados: PERFORM query;


PERFORM create_mv(cs_session_page_requests_mv, my_query);

14/12/2010

Sentencias
No hacer nada: Null; Ejecucin dinmica: EXECUTE texto-comando;
EXECUTE UPDATE tabla SET || quote_ident(nombreCampo) || = || quote_literal(NuevoValor) || WHERE ...;

Obtener resultado de la ltima ejecucin:


GET DIAGNOSTICS variable = item [ , ... ] ; Ejemplos:
GET DIAGNOSTICS Variable_int = ROW_COUNT; -- Cantidad de filas GET DIAGNOSTICS estado = FOUND; -- True/False ltimo resultado

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;

Iterar sobre resultados


Iterar sobre resultados
[<<etiqueta>>] FOR fila IN consulta LOOP sentencias 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;

Abrir cursor para usar:


OPEN unbound_cursor FOR SELECT ...; OPEN unbound_cursor FOR EXECUTE query_string;

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

Mas sobre trigger


CREATE TRIGGER nombre { BEFORE | AFTER } { INSERT | UPDATE | DELETE [ OR ... ] } ON tabla [ FOR [ EACH ] { ROW | STATEMENT } ] EXECUTE PROCEDURE nombre_de_funcin ( argumentos )

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

Potrebbero piacerti anche