IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes PostgreSQL Discussion :

Archiver avant d'effacer


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Par défaut Archiver avant d'effacer
    Bonjour ,

    je dois faire un trigger qui archive de 2 tables différentes avant d'effacer , j'ai donc crée une table pour archiver , mais lorsque que je lance la fonction que j'ai crée pour effacer cela me renvoie une erreur (ma fonction pour effacer fonctionne sans le trigger )

    "ERREUR: l'enregistrement « old » n'a pas de champs « numstage »
    CONTEXT: instruction SQL « insert into archive values (default,old.nometudiant,old.prenometudiant,old.numstage,old.titrestage,old.objetstage,old.anneescolaire,old.numetudiant,old.regimeetudiant,old.numcontact,old.numprofsuiveur,old.remarques) »
    fonction PL/pgsql archivage(), ligne 6 à instruction SQL
    instruction SQL « delete from etudiants where numetudiant = numero »
    fonction PL/pgsql effacetudiant(character varying), ligne 14 à instruction SQL"

    voici ma fonction pour effacer ainsi que mon trigger :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    create or replace function effacetudiant(nometud varchar)
    returns void as
    $$
    declare numero int;
     
    begin 
    perform nometudiant from etudiants where nometudiant=nometud;
    if not found then
    raise exception 'l''etudiant % n''existe pas',$1;
    else
    select numetudiant into numero from etudiants
    	where nometudiant = nometud; 
    delete from periodes where numstage in 
    (select numstage from stages where numetudiant = numero);
     	delete from stages where numetudiant= numero;
    	delete from etudiants where numetudiant = numero;
     
    raise notice 'l''etudiant % a été effacé',$1;
     
    return  ;
    end if;
    end;
    $$
    language plpgsql;


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    create or replace function archivage1() returns trigger as
    $$
     
     
    begin
     
    insert into archive values (default,old.nometudiant,old.prenometudiant,old.numstage,old.titrestage,old.objetstage,old.anneescolaire,old.numetudiant,old.regimeetudiant,old.numcontact,old.numprofsuiveur,old.remarques);
    return old;
    end;
    $$
    language plpgsql;

    si quelqu'un avait une petite idée

    merci d'avance

  2. #2
    Membre Expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Billets dans le blog
    8
    Par défaut
    Salut
    Dans le cas de INSERT, OLD est vide!
    Dans le case de DELETE, NEW est vide!
    Par ailleurs, les lignes...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    perform nometudiant FROM etudiants WHERE nometudiant=nometud;
    IF NOT found then
    raise exception 'l''etudiant % n''existe pas',$1;
    else
    SELECT numetudiant INTO numero FROM etudiants
    	WHERE nometudiant = nometud;
    peuvent être contracter en...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT numetudiant INTO numero FROM etudiants
    	WHERE nometudiant = nometud;
    IF NOT found then
    raise exception 'l''etudiant % n''existe pas',$1;
    else
    ...
    @+

  3. #3
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Par défaut
    Bonjour et merci de ta réponse.

    Mais alors, comment faire pour que le trigger insère dans old les valeurs ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    create or replace function archivage() returns trigger as
    $$
    declare
    nometud varchar;
    prenometud varchar;
    numsta integer;
    titresta varchar;
    objetsta varchar;
    anneescol date;
    numetud integer;
    regimeetud varchar;
    numconta integer;
    numprofsuiv integer;
    remarque varchar;
     
    begin
     
    nometud:=old.nometudiant;   
    select nometudiant into nometud from etudiants where nometudiant=nometud;
    prenometud:=old.prenometudiant;
    select prenometudiant into prenometud from etudiants where prenometudiant=prenometud;
    numsta:=old.numstage;
    select numstage into numsta from stages where numstage=numsta;
    titresta:=old.titrestage;
    select titrestage into titresta from stages where numstage=numsta;
    objetsta:=old.objetstage;
    select objetstage into objetsta from stages where numstage=numsta;
    anneescol:=old.anneescolaire;
    select anneescolaire into anneescol from stages where numstage=numsta;
    numetud:=old.numetudiant;
    select numetudiant into numetud from stages where numstage=numsta;
    regimeetud:=old.regimeetudiant;
    select regimeetudiant into regimeetud from stages where numstage=numsta;
    numconta:=old.numcontact; 
    select numcontact into numconta from stages where numstage=numsta;
    numprofsuiv:=old.numprofsuiveur;
    select numprofsuiveur into numprofsuiv from stages where numstage=numsta;
    remarque:=old.remarques;
    select remarques into remarque from stages where numstage=numsta;
    insert into archive values (default,nometud,prenometud,numsta,titresta,objetsta,anneescol,numetud,regimeetud,numconta,numprofsuiv,remarque);
    return old;
     
    end;
    $$
    language plpgsql;
    Car avec cette requête, même en lui spécifiant les old, il n’insère pas et me renvoie la même erreur.

  4. #4
    Membre Expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Billets dans le blog
    1
    Par défaut
    Salut,

    Tu n'es pas obligée de faire ça dans un trigger...

    Tu peux utiliser returning (qui existe pour update, delete, insert), la syntaxe est détaillée dans la doc postgresql...

    En gros, ça te permet d'enchainer une action qui reprend tout ou partie de ce qui as été fait dans une action d'écriture (update, delete, insert) pour un affichage (select) ou une autre action d'écriture sur une autre table...

  5. #5
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Par défaut
    merci pour ta réponse je regarde ça tout de suite

  6. #6
    Membre Expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Billets dans le blog
    1
    Par défaut
    Ça permet de tout faire en une requête...

    Les triggers vaut mieux qu'ils soient courts vu qu'ils s'exécutent à chaque ligne et s'en passer quand on peut

  7. #7
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Par défaut
    arf ça à l'air très pratique en effet. Le souci est que je dois absolument rendre un trigger pour mon exercice.

    As-tu une idée de ce qui ne va pas dans le trigger que j'ai posté ?

  8. #8
    Membre Expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Billets dans le blog
    1
    Par défaut
    perform ne sert pas à ça... il sert à appeler une fonction sans valeur de retour...

    tu parles de faire l'archivage de 2 tables ou dans 2 tables?

  9. #9
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Par défaut
    bonjour

    de deux tables différentes dans 1 table

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Par défaut
    Apparemment le trigger porterait sur l'effacement dans la table etudiants, donc du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    create trigger nomdutrigger before delete on etudiant for each row execute procedure archivage();
    Si c'est le cas, il faut comprendre que ça implique que OLD.* à l'intérieur de ce trigger a exclusivement les champs de la table etudiants.

    Or le champ numstage n'est pas (apparemment toujours) dans la table etudiants, il serait dans la table stages, c'est pourquoi l'accès à OLD.numstage provoque une erreur.

  11. #11
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Par défaut
    bonjour ,

    J'ai bien créé les triggers correspondants pourtant sur 3 tables (etudiants, stages et periodes)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create trigger archivage before delete on etudiants
    for each row execute procedure archivage();
     
    create trigger archivage before delete on periodes
    for each row execute procedure archivage();
     
    create trigger archivage before delete on stages
    for each row execute procedure archivage();
    ( les tables dont l'effacement se fait )

  12. #12
    Membre Expert
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Par défaut
    As-tu compris que quand on fait OLD.nomdechamp, on ne peut pas mettre n'importe quel nom de colonne dans nomdechamp?

  13. #13
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Par défaut
    je pensais qu'en spécifiant que le old. allait dans une variable déclarée, cela suffisait

  14. #14
    Membre Expert
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Par défaut
    Pour que la même fonction trigger marche en effaçement sur les 3 tables, il faudrait qu'elles aient la même structure.

    Mais elles n'ont pas la même structure, et pire elles ne semblent avoir les mêmes cardinalités par étudiant.

    C'est-à-dire que:

    Est-ce que pour un étudiant donné il peut y avoir plusieurs entrées associées dans la table stages?

    Est-ce que pour un stage donné il peut y avoir plusieurs entrées associées dans la table periode?

    A priori, vu ce qu'on peut déduire du modèle à partir des bouts de code, c'est oui.

    Et dans ce cas l'idée de stocker tout dans une seule table d'archive n'est pas valable.

    Si c'est une idée de toi, l'erreur est là, il faut faire plusieurs tables d'archive de structures différentes.

    Si c'est une obligation de l'énoncé de ton sujet, il faudrait réfléchir sur la base de l'énoncé exact car ça pose un vrai problème conceptuel.

  15. #15
    Membre Expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Billets dans le blog
    1
    Par défaut
    old et new sont des variables spéciales internes aux triggers, elles sont automatiquement déclarées avec un type qui correspond à chaque colonne de la table concernée...

    sur 2 tables c'est possible si tu peux taper dans l'autre avec un truc de celle sur laquelle se produit le trigger.

    ici tu dois faire un trigger after delete (pas la peine d'archiver si tu supprimes pas)...

    à toi de voir donc ce qui relit tes tables et les actions sur la table n°2 (quelle jointure)

    après dans ton trigger c'est un simple insert.... select suivit d'un éventuel delete sur la table n°2

    vu que tu es étudiante... faut bien qu'on te laisse chercher un peu et tester... là,tu as tout ce qui faut...

  16. #16
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Par défaut
    L'idée vient de l'énoncé

    2. Ecrire une procédure qui supprime un étudiant (dont le nom est passé en paramètre) ainsi que les stages auxquels il a participé.

    3. Ecrire un trigger qui archive tous les stages d’un étudiant, avant de le (l’étudiant) supprimer. La table dans laquelle, on archive ayant la même structure que la table stages.

    4. Ecrire une variante améliorée, l’archivage se faisant dans une table dont la structure est la suivante : nometudiant , prenometudiant , numstage, titrestage, objetstage, anneescolaire, numetudiant, regimeetudiant, numcontact, numprofsuiveur, remarques

    la fonction pour la question 2 fonctionne et j' ai le choix entre la question 3 ou 4 que je n'arrive pas à résoudre

  17. #17
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Par défaut
    il me manquerait donc des jointures?

  18. #18
    Membre Expert
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Par défaut
    Pour la question 3 il faut se contenter de copier en trigger la ligne effacée de stage OLD.* vers archive_stage.
    Mais ça se déclenche sur effacement dans stages, pas dans etudiant et il n'y pas de nom d'étudiant dans archive_stage.

    Pour la question 4, un trigger sur effacement dans la table etudiant ne résoudrait pas le problème, au contraire il en pose deux.

    1) problème de cardinalité

    Supposons un étudiant qui a 2 stages, de numéro 1 et 2.
    On dit qu'il faut copier ça dans une structure: nometudiant , prenometudiant , numstage, titrestage, objetstage

    s'il n'y a qu'une seule ligne par étudiant, que mettre dans numstage: 1 ou 2?
    Plus probablement il faut mettre plusieurs lignes par étudiant et nometudiant et prenometudiant sont répétés autant de fois qu'il y a de stages.

    2) problème d'ordre d'effacement
    Normalement il faut effacer dans stages d'abord et dans etudiant après, ne serait-ce qu'à cause des contraintes d'intégrité référentielle.
    Mais dans ce cas le trigger qui se déclencherait sur effacement dans etudiant n'aura plus accès aux stages associés car il sont déjà effacés au moment de son lancement.

  19. #19
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Par défaut
    voila pour la question 3 mais j 'ai toujours une erreur similaire sur un autre champ

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    create or replace function archivage() returns trigger as
    $$
     
     
    begin
     
     
     
       insert into stagesarchive values (default,old.numstage,old.titrestage,old.objetstage,old.anneescolaire,old.numetudiant,old.regimeetudiant,old.numcontact,old.numprofsuiveur,old.remarques); 
     
    return old;
    end;
     
    $$
    language plpgsql;
    drop trigger archivage on stages;
    create trigger archivage before delete on stages
    for each row execute procedure archivage();

  20. #20
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Par défaut
    ou bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    create or replace function archivage() returns trigger as
    $$
     
     
    begin
     
    insert into stagesarchive SELECT old.* FROM stages;
     
    return old;
    end;
     
    $$
    language plpgsql;
    drop trigger archivage on stages;
    create trigger archivage before delete on stages
    for each row execute procedure archivage();
    cela ne fonctionne pas non plus

Discussions similaires

  1. [XL-2003] Copier avant d'effacer
    Par sylvestre09 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 17/04/2012, 16h14
  2. Effacer une ligne pour archiver
    Par laurent.c123 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 04/10/2007, 12h01
  3. script pour demander une confirmation avant d effacer
    Par pierrot10 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 09/10/2006, 10h46
  4. Effacer un Canvas avant de redessiner dessus
    Par Kwentin dans le forum Java ME
    Réponses: 3
    Dernier message: 09/10/2006, 08h21
  5. [VBA-E]Copier avant d'effacer
    Par tarmin dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 23/01/2006, 13h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo