post icon

Como crear triggers a nivel de columnas con PostgreSQL

Hace tan sólo dos días atrás se liberó la versión estable de Postgre 9.0 y la misma acarrea encima un montón de mejoras y cambios que para mí serán considerados Hitos en las Bases de Datos Libres.

Entre las features más interesantes están éstas:

  • Triggers condicionales
  • Triggers por columna
  • Hot Standby
  • Soporte a Windows 64-bit
  • Planes de EXPLAIN en JSON y XML

Hay varios otros, en éste enlace pueden encontrar un pequeño resumen en español de lo que nos ofrecerá la nueva versión: ttp://www.postgresql.org/about/press/presskit90.html.es

En este post me centraré principalmente en los disparadores por columna, que justamente unos días atrás buzzeaba con Juan Cuevas si era posible hacerlo, para sorpresa nuestra ahora sí y es el único motor de BBDD que lo está implementando a la fecha.

Para el ejemplo daré por sentado que saben que hace un trigger y como se crea, además para el ejemplo crearé unas tablas y triggers sin mucho sentido práctico pero si lograrán demostrar el concepto.

Creamos 2 tablas, la primera que tendrá 3 columnas y un trigger en la tercer columna que insertará registros (simulando un log) en otra tabla.

CREATE TABLE "forTrigger"
(
  column1 integer NOT NULL,
  column2 text,
  column3 text,
  CONSTRAINT pk_table PRIMARY KEY (column1)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE "forTrigger" OWNER TO postgres;

CREATE TABLE "logTrigger"
(
  accion text,
  fxhx time without time zone
)
WITH (
  OIDS=FALSE
);
ALTER TABLE "logTrigger" OWNER TO postgres;

Ya tenemos las 2 tablas y seguimos creando la función para el trigger

CREATE OR REPLACE FUNCTION "fxColumna"()
  RETURNS trigger AS
$BODY$begin
  insert into public."logTrigger" values ('Log Update Columna', now());
  return new;
end;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION "fxColumna"() OWNER TO postgres;

Y finalmente asociamos nuestra funcion al trigger por Update. Debemos tener en cuenta que los triggers a nivel de columna sólo se pueden aplicar por Update y no por Insert o Delete, incluso si un trigger se dispara por más de un evento deberán separarlo obligatoriamente. Es un proceso lógico por Insert no tendría sentido porque todas las columnas son afectadas y por delete se aplica directamente sobre una fila, no se puede eliminar sólo columnas.

CREATE TRIGGER "tColumna"
  BEFORE UPDATE OF column3
  ON "forTrigger"
  FOR EACH ROW
  EXECUTE PROCEDURE "fxColumna"(E'\\x');

Comentarios desde Facebook:

Sin Comentarios aun, puedes tú ser el primero en comentar!

Deja tu Comentario

Responder