banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Pour sécuriser votre compte sur les forums du GeoRezo, nous demandons de changer votre mot de passe.

Vous allez recevoir un message pour effectuer ce changement de mot de passe.

Merci de bien respecter les règles préconisées.

#1 Fri 22 September 2023 12:06

Ricola62
Participant assidu
Date d'inscription: 24 Apr 2012
Messages: 166

trigger & clés etrangeres

Bonjour,
Postgresql 14.2
j'ai une table parent
id(pk) nom
1  toto
2  tata
3 popo

une table enfant
id(pk),id_p(fk),date
1, 2, 01/02/2020
2, 1, 03/02/2020
3, 3, 04/02/2020

l'idée est de fusionner toto tata pour donner id 4, de faire update cascade pour que les clés etrangeres soit maj.
cependant faire un update table set id= 4 where id = 1 et  set id= 4 where id = 2 va à l'encontre de la clé primaire et l'unicité.

le résultat devrait être
id(pk) nom
4 [toto,tata]
3 popo

id(pk),id_p(fk),date
1, 4, 01/02/2020
2, 4, 03/02/2020
3, 3, 04/02/2020

Dernière modification par Ricola62 (Fri 22 September 2023 12:21)

Hors ligne

 

#2 Sat 23 September 2023 11:12

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1538

Re: trigger & clés etrangeres

Bonjour,

Il faudrait changer le type de la colonne parent.nom aussi ? pour stocker une liste de valeurs, un tableau de text (text[]) est conseillé.

Une tentative avec une CTE pour faire à la fois un insert dans parent, un update dans enfant, puis un delete dans parent big_smile


On vire la FK d'enfant, on change le type de la colonne parent.nom, puis insert/update/delete, puis rajout de la FK sur enfant:

Code:

drop table if exists parent cascade ;
create table parent (
    id int primary key ,
    nom text
);

insert into parent
values (1, 'toto'),
       (2, 'tata'),
       (3, 'popo');

drop table if exists enfant cascade ;
create table enfant(
    id int primary key ,
    id_p int references parent(id),
    dte date
);

insert into enfant values
(1, 2, '01/02/2020'),
(2, 1, '03/02/2020'),
(3, 3, '04/02/2020');

begin;
alter table enfant drop constraint enfant_id_p_fkey;
alter table parent alter column nom type text[] using array[nom];

-- insert into parent et enfant dans la meme requete pour garder le lien avec l'ancienne pk
with tmp as (
    insert into parent (id, nom)
           select (select max(id) + 1 from parent ) as id, array_agg(nom[1]) as nom
           from parent
           where id in (1, 2)
           -- ou where nom <@ '{toto, tata}'::text[]
       returning id, nom
), tmp1 as (
    update enfant e set id_p = tmp.id
    from tmp, parent p
    where p.nom <@ tmp.nom and e.id_p = p.id

)
delete from parent where id in (1, 2);

alter table enfant add constraint enfant_id_p_fk foreign key (id_p) references parent(id);

commit ;

table parent;
-- +--+-----------+
-- |id|nom        |
-- +--+-----------+
-- |3 |{popo}     |
-- |4 |{toto,tata}|
-- +--+-----------+

table enfant;
-- +--+----+----------+
-- |id|id_p|dte       |
-- +--+----+----------+
-- |1 |4   |2020-01-02|
-- |2 |4   |2020-03-02|
-- |3 |3   |2020-04-02|
-- +--+----+----------+

Nicolas

Hors ligne

 

#3 Mon 25 September 2023 12:04

Ricola62
Participant assidu
Date d'inscription: 24 Apr 2012
Messages: 166

Re: trigger & clés etrangeres

D'accord, merci pour la soluce !

Hors ligne

 

Pied de page des forums

Powered by FluxBB