PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 15/07/2015 14:04:00

MINIX35
Membre

transfert résultat d'un champ d'une table dans une autre

Bonjour,

J'ai 2 tables
Table 1 calcul
-- colonnes
--- calc_int_id  / Clé primaire SERIAL NOT NULL
--- calc_dec_chiffre / NUMERIC (10,2)
--- calc_dec_....

- Table 2 resultat
-- colonnes
--- result_int_id / Clé primaire  SERIAL NOT NULL
--- calc_int_id / Clé étrangère  INTEGER NOT NULL
--- result_dec_chiffre / NUMERIC(10,2) DEFAUT 0
--- result_dec_....

-- Contraintes table resultat
--- pk_resultat / colonne result_int_id / Unique :oui / Primaire : oui
--- fk_resultat_calcul / colonne fille : result_int_id / Reference : calcul(bip_int_id) / Correspondance : simple / Clé étrangére systeme : non


Je dois copier la colonne calc_dec_chiffre ( table calcul)  dans la colonne result_dec_chiffre (table resultat).


Voila ce que j'ai essayé avec des requetes, j'utilise pgadmin.

1er essai
insert into resultat  (result_dec_chiffre) (select  calc_dec_chiffre from calcul);
ce que j'obtiens : ERROR:  null value in column "result_int_id" violates not-null constraint

J'ai donc passer la colonne resultat(result_int_id) de Non Null à possibilité d'être NUL
Ce que j'obtiens : La requête a été exécutée avec succés : 9 lignes modifiées. La requête a été exécutée en 51 ms.
MAIS .....
la table resultat crée de nouvelles lignes avec de nouvelles clés :  result_int_id / Clé primaire  SERIAL NOT NULL, et les champs clés  calc_int_id / Clé étrangère INTEGER NOT NULL sont maintenant vides, malgré que le champ " result_dec_chiffre" de la table soit bien l'équivalent du champ "calc_dec_chiffre"
Donc ca marche pas.


2 nd essai
INSERT INTO resultat  ( result_dec_chiffre)
SELECT
calc_dec_chiffre
FROM
calcul
WHERE (SELECT calc_int_id
FROM resultat) IS NOT NULL;
J'obtiens : ERROR:  more than one row returned by a subquery used as an expression


3ieme essai avec Join
select
resultat.*,
calcul.calc_dec_chiffre
from
resultat
left join
calcul
on
resultat.result_dec_chiffre  = calcul. calc_dec_chiffre;
J'obtiens : la nouvelle colonne "calcul.calc_dec_chiffre" dans ma table resultat, MAIS Vide ....

Vous avez compris.. je débute.. rien ne marche.
pouvez vous m'aider, comment je dois faire ?
Merci par avance
Dan

Question subsidiaire, comment (qui) se déclenche la requete, un trigger je sais, mais une requete ???

Hors ligne

#2 16/07/2015 21:26:27

gleu
Administrateur

Re : transfert résultat d'un champ d'une table dans une autre

Si je comprends bien, vous voulez mettre à jour la valeur d'une colonne pour des lignes existantes. Donc c'est un UPDATE, pas un INSERT. Vous voulez la mettre à jour par rapport au contenu d'une autre table, il faut donc faire une jointure, qui se fait avec un FROM dans un UPDATE. Ça devrait ressembler à ceci :

UPDATE table 1
SET table1.colonne=table2.colonne
FROM table2
WHERE table1.id=table2.id;

Guillaume.

Hors ligne

#3 17/07/2015 13:16:40

MINIX35
Membre

Re : transfert résultat d'un champ d'une table dans une autre

Bonjour,
merci beaucoup pour l'aide, je ne savais plus vers ou aller.. mais maintenant voila le code qui fonctionne :

UPDATE table1
SET     colonnetable1 =
        (   SELECT table2.colonnetable2
            FROM    table2
            WHERE   table1.id= table2.id
        );
J'ai juste une autre question, qui, comment se déclenche la requête ?

Dan

ps : je ne vois pas ou il faut cliquer pour mettre le code dans une fenêtre de présentation ??

Hors ligne

#4 17/07/2015 14:24:15

gleu
Administrateur

Re : transfert résultat d'un champ d'une table dans une autre

C'est vous qui l'exécutez a priori.


Guillaume.

Hors ligne

#5 17/07/2015 15:04:34

MINIX35
Membre

Re : transfert résultat d'un champ d'une table dans une autre

Lorsque je l’exécute manuellement avec pgadmin cela ne pose pas de problème.
Ce que je souhaite est de déclencher automatiquement la requête lorsqu'un utilisateur de l'application modifie une des tables.

Peut être faut il alors un trigger pour exécuter la requete ? mais  si j'enregistre la requête, je ne la retrouve pas dans l'arborescence de pgadmin pour la déclencher, comment alors je peux faire ?

Pgadmin offrant cette arborescence pour chaque table :
- colonne
- contraintes
- index
- régles, dans ce menu j'ai "ajouter" une régle qui m'ouvre une fenêtre avec "propriétés", "définitions", "requetes", "SQL"

J'ai donc recopié ma requete dans régles comme ceci :
- propriéte : nom de la requete
- définition : Update
- requetes : texte de la requete
- SQL 

Mais cela ne déclenche rien après avoir relancé netbeans / glassfish,..

Pouvez vous juste m'indiquer dans quelle direction je dois aller ? Simplement pour m'éviter de "m'embourber" comme précédemment sur des modèles d'actions qui n'étaient pas bons..
Dan

Hors ligne

#6 17/07/2015 21:20:15

gleu
Administrateur

Re : transfert résultat d'un champ d'une table dans une autre

Il faut passer par un trigger en effet.


Guillaume.

Hors ligne

#7 18/07/2015 12:53:41

MINIX35
Membre

Re : transfert résultat d'un champ d'une table dans une autre

bonjour,

si je dois passer par un trigger, à quoi sert la requête ? autant faire un trigger directement ?
A ce moment là, je vois pas l'intérêt d'une requête, il y a qqchose qui m'échappe dans la méthode .

J'ai donc fait un trigger direct en reprenant les codes de la requête comme ceci  :

CREATE TRIGGER "ReqBIU"
  BEFORE INSERT OR UPDATE
  ON table1
  FOR EACH ROW
  EXECUTE PROCEDURE "13072015_1"();

puis la procédure
CREATE OR REPLACE FUNCTION "13072015_1"()
  RETURNS trigger AS
$BODY$BEGIN
UPDATE table1
SET     colonne1 =
        (   SELECT  table2.colonne2
            FROM   table2
            WHERE   table1.id = table2.id
        );
RETURN NEW;
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION "13072015_1"()
  OWNER TO xxxxxxx;

..ET CA MARCHE !!! mais seulement si je rajoute "RETURN NEW;" sinon postgres plante glassfish ( ça, je comprends pas pourquoi ..., j'ai pas de New..).

Si vous pouviez juste y jeter un dernier oeil,  ensuite je ne vous embêterai plus ( enfin .. pas pour ça ..)
Merci encore de votre coup de pouce, c'est sympa et pas si fréquent que l'on pense, j'en avais bien besoin
dan

Hors ligne

#8 18/07/2015 14:30:09

gleu
Administrateur

Re : transfert résultat d'un champ d'une table dans une autre

NEW est une variable interne correspondant à la ligne en cours d'insertion ou modifiée. Il est nécessaire de renvoyer une valeur dans une fonction trigger lors d'un INSERT ou d'un UPDATE.


Guillaume.

Hors ligne

#9 19/07/2015 12:54:48

MINIX35
Membre

Re : transfert résultat d'un champ d'une table dans une autre

Bonjour,
je vais maintenant tenter avec 3 tables croisées, c'est à dire table 1 en lien avec table2, table 2 en lien avec table 3, mon but étant de copier une colonne x de la table 1 dans une colonne x' de  la table3
Si ce la ne vous ennuie pas, je reviendrai vers vous sous huitaine avec mes codes.
Même méthode, test avec requête et transformation en trigger.
dan

Hors ligne

#10 01/08/2015 13:30:08

MINIX35
Membre

Re : transfert résultat d'un champ d'une table dans une autre

Bonjour,
ma difficulté précédente est Ok.
J'ai un autre souçi que je ne comprends pas
J'ai 2 tables, le but est de transférer une donné de la 1ére dans la 2 ieme sous conditions.

Ma table_origine
org.int.id  Pk serial  |   champ1_vch    |  atransferer_dec |
---------------------------------------------------------------------
128                         |           A               |            10              |
---------------------------------------------------------------------
129                         |           B               |            20             |
---------------------------------------------------------------------
120                         |           C               |            30             |
---------------------------------------------------------------------

Ma table_copie
cop.int.id  Pk serial  |   champ1_vch   |       copie_dec        |
---------------------------------------------------------------------
1000                        |           A              |                                |
---------------------------------------------------------------------
1001                        |           A              |                                |
---------------------------------------------------------------------
1002                        |           A              |                                |
---------------------------------------------------------------------
1003                        |           B              |                                |
---------------------------------------------------------------------
1004                        |           B              |                                |
---------------------------------------------------------------------
etc..

Les conditions :
champ1_vch de chaque table doivent identiques pour que atransferer_dec soit transférer vers   copie_dec

Le problème que je rencontre est lorsque je lance mon trigger :
-  j'ajoute une nouvelle clé  "cop.int.id  Pk serial" en créant une nouvelle ligne dans ma table copie, et ça recopie bien ma donnée à transférer de la table origine, donc tout baigne ..
sauf que lorsque j'entre une 2nd ligne ( donc avec une nouvelle clé cop_int_id), ça copie bien ma donnée"champ1_vch"  à transférer mais ça m'efface la 1ére, c'est ça que je comprends pas.

Voila le code :

BEGIN
IF (TG_OP = 'INSERT' ) THEN
update table_copie
SET     copie_dec =
       (   SELECT table_originel. atransferer_dec
            FROM    table_origine
           WHERE  table_copier. champ1_vch  = table_origine.champ1_vch 
            AND   copie_dec_previ is DISTINCT FROM  atransferer_dec
        );
END IF;
RETURN NEW;
END;

OU est mon erreur ?
Merci de votre aide
dan

Hors ligne

#11 01/08/2015 17:26:30

rjuju
Administrateur

Re : transfert résultat d'un champ d'une table dans une autre

À priori vous n'insérez pas de lignes dans la table copie, mais vous mettez à jour l'intégralité de la table table_copie (UPDATE et non INSERT) avec une seule valeur (votre update n'a pas de condition WHERE).

Hors ligne

#12 01/08/2015 18:55:20

MINIX35
Membre

Re : transfert résultat d'un champ d'une table dans une autre

Bonjour Julien,
Merci de votre conseil.

Je croyais que " insert into" intégrait toute une ligne à la fois ? alors je ne l'employais pas,  parce que voila comment cela se déroule :

- Je rempli un formulaire qui, lorsque je le valide, enregistre ces données dans ma table "copie" et génère donc une nouvelle ligne de données    " cop.int.id  Pk serial  |   champ1_vch   |   copie_dec   | "
- J'ai donc configuré mon trigger en "after" pour le déclencher après la validation du formulaire ( donc après l'enregistrement de ses données dans  " table_copie   " | cop.int.id  Pk serial | ... | ... | .. " )
- résultat  : création d'une nouvelle ligne dans table_copie, enregistrement des données du formulaire ( ça c'est Ok) + enregistrement conditionnel d'une donnée de la table table_origine ( pas OK)
Je ne sais pas si cette explication peut avoir un effet dans votre conseil.

J'ai donc fait ce code avec insert, mais cela empêche que la validation du formulaire enregistre ses données dans la nouvelle ligne de la table_copie    "cop.int.id  Pk serial" | .. |

BEGIN
insert into table_copie (copie_dec)
select table_origine.atransferer_dec from table_origine
where 
table_copier. champ1_vch  = table_origine.champ1_vch 
AND   -- pour vérifier que la nouvelle ligne a bien été créée par le formulaire
cop.int.id is not null;
RETURN NEW;
END;

IL y a qqchose qui m'échappe..

Dernière modification par MINIX35 (01/08/2015 18:55:58)

Hors ligne

#13 10/08/2015 16:57:36

MINIX35
Membre

Re : transfert résultat d'un champ d'une table dans une autre

RESOLU en update avec des alias.. enfin

Hors ligne

Pied de page des forums