En PostgreSQL 8, ¿es posible agregar ON DELETE CASCADES
a ambas claves foráneas en la siguiente tabla sin soltar la última?
# \d scores
Table "public.scores"
Column | Type | Modifiers
---------+-----------------------+-----------
id | character varying(32) |
gid | integer |
money | integer | not null
quit | boolean |
last_ip | inet |
Foreign-key constraints:
"scores_gid_fkey" FOREIGN KEY (gid) REFERENCES games(gid)
"scores_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
Ambas tablas referenciadas están abajo - aquí:
# \d games
Table "public.games"
Column | Type | Modifiers
----------+-----------------------------+----------------------------------------------------------
gid | integer | not null default nextval('games_gid_seq'::regclass)
rounds | integer | not null
finished | timestamp without time zone | default now()
Indexes:
"games_pkey" PRIMARY KEY, btree (gid)
Referenced by:
TABLE "scores" CONSTRAINT "scores_gid_fkey" FOREIGN KEY (gid) REFERENCES games(gid)
Y aquí:
# \d users
Table "public.users"
Column | Type | Modifiers
------------+-----------------------------+---------------
id | character varying(32) | not null
first_name | character varying(64) |
last_name | character varying(64) |
female | boolean |
avatar | character varying(128) |
city | character varying(64) |
login | timestamp without time zone | default now()
last_ip | inet |
logout | timestamp without time zone |
vip | timestamp without time zone |
mail | character varying(254) |
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "cards" CONSTRAINT "cards_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "catch" CONSTRAINT "catch_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "chat" CONSTRAINT "chat_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "game" CONSTRAINT "game_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "hand" CONSTRAINT "hand_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "luck" CONSTRAINT "luck_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "match" CONSTRAINT "match_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "misere" CONSTRAINT "misere_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "money" CONSTRAINT "money_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "pass" CONSTRAINT "pass_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "payment" CONSTRAINT "payment_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "rep" CONSTRAINT "rep_author_fkey" FOREIGN KEY (author) REFERENCES users(id)
TABLE "rep" CONSTRAINT "rep_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "scores" CONSTRAINT "scores_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
TABLE "status" CONSTRAINT "status_id_fkey" FOREIGN KEY (id) REFERENCES users(id)
Y también me pregunto si tiene sentido agregar 2 índices a la tabla anterior.
ACTUALIZACIÓN: Gracias, y también recibí el consejo en la lista de correo, de que podría administrarlo en 1 declaración y, por lo tanto, sin iniciar explícitamente una transacción:
ALTER TABLE public.scores
DROP CONSTRAINT scores_gid_fkey,
ADD CONSTRAINT scores_gid_fkey
FOREIGN KEY (gid)
REFERENCES games(gid)
ON DELETE CASCADE;
postgresql
constraints
cascade
cascading-deletes
postgresql-8.4
Alexander Farber
fuente
fuente
pref_scores.gid
). Las eliminaciones en la tabla referenciada tardarán mucho tiempo sin ellas, si obtiene muchas filas en esas tablas. Algunas bases de datos crean automáticamente un índice en las columnas de referencia; PostgreSQL lo deja a usted, ya que hay algunos casos en los que no vale la pena.Respuestas:
Estoy bastante seguro de que no puede simplemente agregar
on delete cascade
a una restricción de clave externa existente. Primero debe eliminar la restricción y luego agregar la versión correcta. En SQL estándar, creo que la forma más fácil de hacer esto eson delete cascade
, y finalmenteRepita para cada clave externa que desee cambiar.
Pero PostgreSQL tiene una extensión no estándar que le permite usar múltiples cláusulas de restricción en una sola instrucción SQL. Por ejemplo
Si no conoce el nombre de la restricción de clave externa que desea eliminar, puede buscarla en pgAdminIII (simplemente haga clic en el nombre de la tabla y mire el DDL, o expanda la jerarquía hasta que vea "Restricciones"), o puede consultar el esquema de información .
fuente
NOT VALID
y validar en una transacción separada? Tengo una pregunta sin respuesta sobre esto.Basado en la respuesta de @Mike Sherrill Cat Recall, esto es lo que funcionó para mí:
fuente
Uso:
Función:
Tenga en cuenta: esta función no copiará los atributos de la clave externa inicial. Solo toma el nombre de la tabla / columna extranjera, elimina la clave actual y la reemplaza por una nueva.
fuente