Dans PostgreSQL 8, est-il possible d'ajouter ON DELETE CASCADES
les deux clés étrangères dans le tableau suivant sans supprimer cette dernière?
# \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)
Les deux tableaux référencés sont ci-dessous - ici:
# \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)
Et ici:
# \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)
Et aussi je me demande s'il est logique d'ajouter 2 index à l'ancienne table?
MISE À JOUR: Merci, et aussi j'ai eu le conseil à la liste de diffusion, que je pourrais le gérer en 1 déclaration et donc sans démarrer explicitement une transaction:
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
la source
la source
pref_scores.gid
). Les suppressions sur la table référencée prendront beaucoup de temps sans celles-ci, si vous obtenez de nombreuses lignes dans ces tables. Certaines bases de données créent automatiquement un index sur la ou les colonnes de référence; PostgreSQL vous laisse le soin, car il y a des cas où cela ne vaut pas la peine.Réponses:
Je suis presque sûr que vous ne pouvez pas simplement ajouter
on delete cascade
à une contrainte de clé étrangère existante. Vous devez d'abord supprimer la contrainte, puis ajouter la version correcte. En SQL standard, je pense que le moyen le plus simple de le faire est deon delete cascade
, et enfinRépétez pour chaque clé étrangère que vous souhaitez modifier.
Mais PostgreSQL a une extension non standard qui vous permet d'utiliser plusieurs clauses de contrainte dans une seule instruction SQL. Par exemple
Si vous ne connaissez pas le nom de la contrainte de clé étrangère que vous souhaitez supprimer, vous pouvez soit le rechercher dans pgAdminIII (cliquez simplement sur le nom de la table et regardez le DDL, soit développez la hiérarchie jusqu'à ce que vous voyiez «Contraintes»), ou vous pouvez interroger le schéma d'informations .
la source
NOT VALID
et valider dans une transaction séparée? J'ai une question sans réponse à ce sujet.Basé sur la réponse de @Mike Sherrill Cat Recall, voici ce qui a fonctionné pour moi:
la source
Usage:
Fonction:
Attention: cette fonction ne copiera pas les attributs de la clé étrangère initiale. Il prend uniquement le nom de la table / colonne étrangère, supprime la clé actuelle et la remplace par une nouvelle.
la source