sobre transacciones...

From: "Br(at)nsh" <bransh(at)gmail(dot)com>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: sobre transacciones...
Date: 2008-01-12 23:28:19
Message-ID: 47894D13.4050708@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Antes que nada, saludo a toda la comunidad de Postgres. Esta es la
primera vez que escribo en la lista.

Hace poco mas de medio año que estoy utilizando postgres version 8 y
normalmente me recorro la web completa para solucionar los problemas que
se me presentan. Pero en este caso, no encontre respuesta y quizas pueda
deberse a mi falta de imaginacion ;-)

Bueno, paso a explicarme:
Supongamos tengo 2 tablas:

Provincias (idProvincias, nombre)
Localidades (idLocalidad, idProvincia, nombre)

Ahora bien, estan relacionadas de manera Identificada (es decir, que en
la tabla Localidades, idProvincia forma parte de la clave primaria).

Supongamos ahora que tengo los siguientes registros:

Tabla Provincias:
idP = 1, nombre = "Cualquiera"

Tabla Localidades:
idL = 1, idP = 1, nombre = "Uno"
idL = 2, idP = 1, nombre = "Dos"

Bueno. Tengo una funcion escrita en plpgsql que dado un idP borra la
provincia del id correspondiente, o al menos eso intenta siempre que no
se este por violar una integridad referencial:
--
-- Borrar Provincia
--
CREATE OR REPLACE FUNCTION
ssp_borrar_provincia(Provincias.idProvincia%TYPE)
RETURNS Provincias.idProvincia%TYPE AS $$
DECLARE
idP ALIAS FOR $1;
BEGIN
--Comprobamos que el idProvincia sea valido
IF idP IS NULL OR idP = 0 THEN
RAISE EXCEPTION 'El valor de la columna IDPROVINCIA no debe ser
nulo ni cero.';
END IF;

DELETE
FROM Provincias
WHERE idProvincia = idP;

RETURN idP;
END;
$$ LANGUAGE 'plpgsql';

Ahora, mi intencion es hacer una FUNCION que borre una cierta localidad
de la tabla Localidades, y luego intente borrar la provincia a la que
pertence. (se que parece no tener mucho sentido, pero lo que necesito
hacer bajo este concepto si lo tiene, y es demasiado largo como para
exponerlo en una consulta, digamos que se aburririan y no querrian
contestarla, ;-)).

Bueno, la idea seria esto:

CREATE OR REPLACE FUNCTION
ssp_borrar_localidad(Localidades.idLocalidad%TYPE)
RETURNS Localidades.idLocalidad%TYPE AS $$
DECLARE
idL ALIAS FOR $1;
idP Localidades.idProvincia%TYPE;
BEGIN
--Comprobamos que el idLocalidad sea valido
IF idL IS NULL OR idL = 0 THEN
RAISE EXCEPTION 'El valor de la columna IDLOCALIDAD no debe ser
nulo ni cero.';
END IF;

--Buscamos el idProvincias correspondiente a la localidad que se
desea borrar
SELECT INTO idP idProvincia
FROM Localidades
WHERE idLocalidad = idL;

DELETE
FROM Localidades
WHERE idLocalidad = idL;

--Intentamos borrar la provincia
SELECT ssp_borrar_provincia(idP);

RETURN idL;
END;
$$ LANGUAGE 'plpgsql';

Ahora el gran problema: Claro esta que lo que quiero es que borre la
localidad y en caso de que se pueda, borre la provincia. Peeero, resulta
que al ocurrir un error de Violacion de Integridad Referencial en el
intento por borrar la provincia al final de la funcion, automaticamente
se hace un ROLLBACK de toda la funcion principal (ssp_borrar_localidad)
y ni siquiera me borra la localidad.

Que solucion me proponen?

Desde ya muchisimas gracias!!

Juan Caillava

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Ever Daniel Barreto Rojas 2008-01-13 00:38:59 Re[2]: ERROR: se ha detectado un deadlock
Previous Message Oswaldo Hernández 2008-01-12 19:10:56 Re: ERROR: se ha detectado un deadlock