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é ?

#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: 1542

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