#1 Fri 22 September 2023 12:06
- Ricola62
- Participant assidu
- Date d'inscription: 24 Apr 2012
- Messages: 167
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: 1566
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 
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: 167
Re: trigger & clés etrangeres
D'accord, merci pour la soluce !
Hors ligne





