[Pgsql-ayuda] Llaves foráneas

Patricio Muñoz pmunoz@cmet.net
Thu, 17 Jul 2003 16:00:32 -0400


Estimados,
Al momento de crear llave(s) foránea(s) en una tabla, el orden importa al
momento de ser creadas, por ej. en la siguiente estructura:

CREATE TABLE "a" (
 "id_a" int2 NOT NULL,
 "id_b" int2 NOT NULL REFERENCES b ON UPDATE CASCADE ON DELETE CASCADE,
 "nombre" varchar(15) NOT NULL,
 PRIMARY KEY ("id_a"),
 FOREIGN KEY ("id_b") REFERENCES b
);

CREATE TABLE "b" (
 "id_b" int2 NOT NULL,
 "nombre" varchar(15) NOT NULL,
 PRIMARY KEY ("id_b")
);

Al tener esta estructura en un archivo, y en el mismo orden que aparece
arroja un mensaje (NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit
index 'b_pkey' for table 'b'CREATE) y no crea la tabla, y suena lógico ya
que en la tabla a se hace referencia a la tabla b, donde en un primer
momento no ha sido creada, bueno mi pregunta apunta a que si existe una
cantidad de tablas considerable tendría que crearlas en orden para que no
curriera lo anteriror. Lo que hice fue crearlas en el orden para que no
ocurriera el error mensionado anteriormente, luego ejecute un pg_dump a un
archivo y observe la estructura que crea PostgreSql (para poder seguir el
ejemplo). el resultado fue el sgte:

CREATE TABLE "b" (
        "id_b" smallint NOT NULL,
        "nombre" character varying(15) NOT NULL,
        Constraint "b_pkey" Primary Key ("id_b")
);

CREATE TABLE "a" (
        "id_a" smallint NOT NULL,
        "id_b" smallint NOT NULL,
        "nombre" character varying(15) NOT NULL,
        Constraint "a_pkey" Primary Key ("id_a")
);

CREATE CONSTRAINT TRIGGER "<unnamed>"
AFTER INSERT OR UPDATE ON "a"  FROM "b" NOT DEFERRABLE INITIALLY IMMEDIATE
FOR EACH ROW EXECUTE PROCEDURE "RI_FKey_check_ins" ('<unnamed>', 'a', 'b',
'UNSPECIFIED', 'id_b', 'id_b');

CREATE CONSTRAINT TRIGGER "<unnamed>"
AFTER DELETE ON "b"  FROM "a" NOT DEFERRABLE INITIALLY IMMEDIATE
FOR EACH ROW EXECUTE PROCEDURE "RI_FKey_cascade_del" ('<unnamed>', 'a', 'b',
'UNSPECIFIED', 'id_b', 'id_b');

CREATE CONSTRAINT TRIGGER "<unnamed>"
AFTER UPDATE ON "b"  FROM "a" NOT DEFERRABLE INITIALLY IMMEDIATE
FOR EACH ROW EXECUTE PROCEDURE "RI_FKey_cascade_upd" ('<unnamed>', 'a', 'b',
'UNSPECIFIED', 'id_b', 'id_b');

CREATE CONSTRAINT TRIGGER "<unnamed>"
AFTER INSERT OR UPDATE ON "a"  FROM "b" NOT DEFERRABLE INITIALLY IMMEDIATE
FOR EACH ROW EXECUTE PROCEDURE "RI_FKey_check_ins" ('<unnamed>', 'a', 'b',
'UNSPECIFIED', 'id_b', 'id_b');

CREATE CONSTRAINT TRIGGER "<unnamed>"
AFTER DELETE ON "b"  FROM "a" NOT DEFERRABLE INITIALLY IMMEDIATE
FOR EACH ROW EXECUTE PROCEDURE "RI_FKey_noaction_del" ('<unnamed>', 'a',
'b', 'UNSPECIFIED', 'id_b', 'id_b');

pd: "Quite los comentareos y los copy para hacer mas legible el mail."

De esta manera se evita crear las tablas en un orden específico, para ello
se usa la clausula Constraint y luego se crean los CONSTRAINT TRIGGER.
Después de esta breve introducción :-) .. quisiera saber de que manera puedo
hacer lo mismo sin tener que escribir cada uno de esos TRIGGER.

De antemano gracias

saludos