From: | Gunnar Wolf <gwolf(at)gwolf(dot)org> |
---|---|
To: | Norman Mauricio Garcia <normangarcia64(at)yahoo(dot)co(dot)uk> |
Cc: | pgsql-es-ayuda(at)postgresql(dot)org |
Subject: | Re: Copiar contenido de campo Blob |
Date: | 2007-02-09 19:52:06 |
Message-ID: | 20070209195206.GB25894@gwolf.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-es-ayuda |
Norman Mauricio Garcia dijo [Fri, Feb 09, 2007 at 03:33:40PM +0000]:
> Saludos lista,
>
> Tengo una tabla con un campo de tipo large object (oid me sale en la
> definición de la tabla). Ahora, estoy interesado en crear una copia
> del campo en otro registro, me explico. Digamos que estoy guardando
> un archivo pdf, pero quiero crear una copia de manera que si el
> usuario elimina el registro o cambia el archivo pdf el original siga
> intacto.
>
> Se que puedo extraer el contenido del oid al sistema de archivos y
> volver a cargarlo a la base de datos con lo_import para crear un
> nuevo oid, pero me gustaría saber si existe una forma de hacerlo
> directamente con PostgreSql.
Hola,
Además de lo que los demás señalan, te sugiero considerar no usar
large objects referenciados por OIDs, sino que guardar tus datos en un
campo tipo bytea - No sólo su uso es más natural (directamente con tus
queridos select/insert/update/delete de toda la vida), sino que no
corres riesgos de perder espacio innecesario por usar un OID y perder
referencia a él. Además, usando campos estándar en una tabla, puedes
crear triggers para hacer esto que requieres. Claro, ten en
consideración que hacer manipulaciones como esta puede ser muy pesado,
especialmente si hablamos de archivos grandes. Imagina, pues, que
tengas:
CREATE TABLE documento (
id serial primary key,
titulo text NOT NULL,
filename text NOT NULL UNIQUE,
data bytea);
Antes que otra cosa, seguro te conviene indexar por nombre de archivo:
CREATE INDEX documento_filename ON documento(filename);
Y vas a mantener una tabla con una bitácora de cambios:
CREATE TABLE bitacora (
id serial primary key,
hora_cambio timestamp NOT NULL DEFAULT now(),
filename text NOT NULL,
operacion integer check (operacion >= 1 AND operacion <= 3),
old_data bytea
);
Nota que acá filename no es UNIQUE, pues un mismo archivo puede ser
eliminado o re-creado a lo largo del tiempo. Vamos a crear las funciones
- Aclaro: Estoy escribiendo directo al correo, puede que todo lo que
acá ponga esté plagado de errorres :) Pero la idea se mantiene. Estoy
empleando la horrible técnica de asignar valores (y por eso el check
de la operación) de un catálogo duro - Creación es 1, actualización 2,
remoción 3. Seguro puedes hacer algo más limpio ;-)
CREATE FUNCTION crea_doc_a_bitacora() RETURNS trigger AS
'BEGIN
INSERT INTO bitacora (filename, operacion) VALUES
(NEW.filename, 1);
END;' LANGUAGE 'plpgsql';
CREATE TRIGGER crea_doc_a_bitacora BEFORE INSERT ON documento
FOR EACH ROW EXECUTE PROCEDURE crea_doc_a_bitacora();
CREATE FUNCTION actualiza_doc_a_bitacora() RETURNS trigger AS
'BEGIN
INSERT INTO bitacora (filename, old_data, operacion) VALUES
(OLD.filename, OLD.data, 2);
END;' LANGUAGE 'plpgsql';
CREATE TRIGGER actualiza_doc_a_bitacora BEFORE INSERT ON documento
FOR EACH ROW EXECUTE PROCEDURE actualiza_doc_a_bitacora();
CREATE FUNCTION borra_doc_a_bitacora() RETURNS trigger AS
'BEGIN
INSERT INTO bitacora (filename, old_data, operacion) VALUES
(OLD.filename, OLD.data, 3);
END;' LANGUAGE 'plpgsql';
CREATE TRIGGER borra_doc_a_bitacora BEFORE INSERT ON documento
FOR EACH ROW EXECUTE PROCEDURE borra_doc_a_bitacora();
Espero que quede claro y -más aún- que sea útil :)
Saludos,
--
Gunnar Wolf - gwolf(at)gwolf(dot)org - (+52-55)5623-0154 / 1451-2244
PGP key 1024D/8BB527AF 2001-10-23
Fingerprint: 0C79 D2D1 2C4E 9CE4 5973 F800 D80E F35A 8BB5 27AF
From | Date | Subject | |
---|---|---|---|
Next Message | Jose Stragnari | 2007-02-09 20:10:39 | RE: Problema en ADO con campos text |
Previous Message | Jose Stragnari | 2007-02-09 19:03:10 | Problema en ADO con campos text |