No PostgreSQL 8, é possível adicionar ON DELETE CASCADES
as duas chaves estrangeiras na tabela a seguir sem descartar a ú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 as tabelas referenciadas estão abaixo - aqui:
# \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)
E aqui:
# \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)
E também me pergunto se faz sentido adicionar 2 index'es à tabela anterior?
UPDATE: Obrigado, e também tenho os conselhos na lista de discussão, de que eu poderia gerenciá-lo em uma instrução e, portanto, sem iniciar explicitamente uma transação:
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
fonte
fonte
pref_scores.gid
). As exclusões na tabela referenciada levarão muito tempo sem essas, se você receber muitas linhas nessas tabelas. Alguns bancos de dados criam automaticamente um índice nas colunas de referência; O PostgreSQL deixa isso para você, pois há alguns casos em que não vale a pena.Respostas:
Tenho certeza de que você não pode simplesmente adicionar
on delete cascade
a uma restrição de chave estrangeira existente. Você deve eliminar a restrição primeiro e depois adicionar a versão correta. No SQL padrão, acredito que a maneira mais fácil de fazer isso éon delete cascade
, e finalmenteRepita para cada chave estrangeira que deseja alterar.
Mas o PostgreSQL possui uma extensão não padrão que permite usar várias cláusulas de restrição em uma única instrução SQL. Por exemplo
Se você não souber o nome da restrição de chave estrangeira que deseja eliminar, procure-o no pgAdminIII (basta clicar no nome da tabela e olhar para o DDL ou expandir a hierarquia até ver "Restrições"), ou você pode consultar o esquema de informações .
fonte
NOT VALID
e validando em uma transação separada? Eu tenho uma pergunta sem resposta sobre isso.Baseado na resposta de Mike Sherrill Cat Recall, foi o que funcionou para mim:
fonte
Uso:
Função:
Esteja ciente: esta função não copiará atributos da chave estrangeira inicial. Leva apenas o nome da tabela estrangeira / nome da coluna, descarta a chave atual e substitui pela nova.
fonte