martes, diciembre 16, 2008

Composición a Nivel de Datos


Hablando de la composición, Martin Fowler en su libro UML gota a gota, expone lo siguiente: "... el objeto parte puede pertenecer a un todo único; es más, se espera, por lo general, que las partes vivan y mueran con el todo. Cualquier borrado del todo se extiende en cascada a las partes". Pero en la práctica, ¿Cómo logramos este borrado en cascada?. Si estuviéramos hablando de información almacenada en una base de datos, ¿Borramos los registros en la Tabla Hijo y luego en Padre? ¿Existe alguna otra manera que se acerque más a lo expresado por Fowler?.

Vamos a tomar un ejemplo simple.

- Primero creamos la tabla Padre.

En Oracle:


create table Padre (
id_padre number primary key,
name_padre varchar2(10)
)


En PostgreSQL:


create table Padre (
id_padre numeric primary key,
nombre_padre VARCHAR(10)
);



Luego creamos la tabla Hijo:

En Oracle:


create table Hijo (
id number primary key,
name varchar(10),
id_padre number references Padre (id_padre) on delete cascade
)


En PostgreSQL:


create table Hijo (
id_hijo numeric primary key,
nombre_hijo varchar(10),
id_padre numeric references Padre(id_padre) on delete cascade
)


Ya estamos listos. Si insertamos datos en ambas tablas y luego borramos un registro de Padre, por ejemplo,

delete from Padre
where id_padre = 1;

automáticamente se borrarán todos los registros Hijo asociados a ese Padre.

Espero que les sea útil.

Etiquetas: , ,

jueves, noviembre 22, 2007

Función Obtiene Dígito Verificador en PL/pgSQL (PostgreSQL)

En los últimos años he comenzado un estudio de PostgreSQL como Gestor de Base de Datos y la verdad me he llevado una buena impresión. Un gestor robusto, con un buen manejo de las transacciones y con la maravilla que me tiene como niño con juguete nuevo, PL/pgSQL. Aquí les dejo una función que calcula el dígito verificador de un rut (Chile) en PL/pgSQL.



CREATE FUNCTION OBTIENE_DRUT (NUMERIC)
RETURNS CHAR AS
$$

DECLARE
SUMA INT := 0;
FACTOR INT := 2;
RUT_AUX INT := $1;
DIG INT;
DV INT;

BEGIN
WHILE
(RUT_AUX > 0) LOOP
DIG := RUT_AUX % 10;
IF(FACTOR = 8) THEN
FACTOR := 2;
END IF;

SUMA := SUMA + (DIG * FACTOR);
RUT_AUX := RUT_AUX / 10;
FACTOR := FACTOR + 1;
END LOOP;

DV := 11 - (SUMA % 11);

IF(DV = 10) THEN
RETURN 'K';
ELSIF(DV = 11) THEN
RETURN 0;
ELSE
RETURN DV;
END IF;

END;
$$
LANGUAGE plpgsql;


Etiquetas: , ,