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 :

[trigger] pour supprimer une clef étrangère


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre du Club
    Inscrit en
    Juin 2009
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 64
    Points : 42
    Points
    42
    Par défaut [trigger] pour supprimer une clef étrangère
    Bonjour,

    je dispose d'une table consulta qui contient entre autre une colonne fkDrogas qui fait référence à l'identifiant idDrogas de la table Drogas

    je suis en train d'écrire le delete pour supprimer une ligne de la table consulta et bien entendu comme les fk sont utilisés il ne veut pas

    je voulais donc faire un trigger qui supprime la ligne dans la table Drogas avant de supprimer la table consulta

    voici mon bout de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE FUNCTION del() RETURNS TRIGGER AS
    $$
    BEGIN
     DELETE FROM public."Drogas" WHERE public."Drogas"."idDrogas" = public."Consulta"."fkDrogas";
    END
    $$ LANGUAGE plpgsql;
     
    CREATE TRIGGER del_drog BEFORE DELETE ON public."Consulta" 
    FOR EACH ROW EXECUTE PROCEDURE del();
    ça à l'air de fonctionner mais je sais pas où les mettre dans pgAdmin III...???

  2. #2
    Membre du Club
    Inscrit en
    Juin 2009
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 64
    Points : 42
    Points
    42
    Par défaut
    il fallait attendre qu'il se mette à jour... 30 minutes plsu tard :s

  3. #3
    Membre du Club
    Inscrit en
    Juin 2009
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 64
    Points : 42
    Points
    42
    Par défaut
    au final ma fonction et mon trigger ressemble à ça
    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
    DROP TRIGGER del_drog ON "Consulta";
     
    DROP FUNCTION del();
     
    CREATE FUNCTION del_consulta() RETURNS TRIGGER AS
    $$
    BEGIN
     DELETE FROM public."Drogas" WHERE public."Drogas"."idDrogas" = public."Consulta"."fkDrogas";
     DELETE FROM public."AgudezaVisual" WHERE public."AgudezaVisual"."idAgudezaVisual" = public."Consulta"."fkAgudezaVisual";
     DELETE FROM public."Alcohol" WHERE public."Alcohol"."idAlcohol" = public."Consulta"."fkAlcohol";
     DELETE FROM public."Alimentacion" WHERE public."Alimentacion"."idAlimentacion" = public."Consulta"."fkAlimentacion";
     DELETE FROM public."Audioscopia" WHERE public."Audioscopia"."idAudioscopia" = public."Consulta"."fkAudioscopia";
     DELETE FROM public."Bilan" WHERE public."Bilan"."idBilan" = public."Consulta"."fkBilan";
     DELETE FROM public."Cigarillos" WHERE public."Cigarillos"."idCigarillos" = public."Consulta"."fkCigarillos";
     DELETE FROM public."Cronico" WHERE public."Cronico"."idCronico" = public."Consulta"."fkCronico";
     DELETE FROM public."Depresion" WHERE public."Depresion"."idDepresion" = public."Consulta"."fkDepresion";
     DELETE FROM public."Educacion" WHERE public."Educacion"."idEducacion" = public."Consulta"."fkEducacion";
     DELETE FROM public."Extraescolar" WHERE public."Extraescolar"."idExtraescolar" = public."Consulta"."fkExtra";
     DELETE FROM public."Familiares" WHERE public."Familiares"."idFamiliares" = public."Consulta"."fkFamiliares";
     DELETE FROM public."Fisico" WHERE public."Fisico"."idFisico" = public."Consulta"."fkFisico";
     DELETE FROM public."Hogar" WHERE public."Hogar"."idHogar" = public."Consulta"."fkHogar";
     DELETE FROM public."Menarquia" WHERE public."Menarquia"."idMenarquia" = public."Consulta"."fkMenarquia";
     DELETE FROM public."Observaciones" WHERE public."Observaciones"."idObservaciones" = public."Consulta"."fkObservaciones";
     DELETE FROM public."Orina" WHERE public."Orina"."idOrina" = public."Consulta"."fkOrina";
     DELETE FROM public."Personales" WHERE public."Personales"."idPersonales" = public."Consulta"."fkPersonales";
     DELETE FROM public."Sexualidad" WHERE public."Sexualidad"."idSexualidad" = public."Consulta"."fkSexualidad";
     DELETE FROM public."Sueno" WHERE public."Sueno"."idSueno" = public."Consulta"."fkSueno";
    END
    $$ LANGUAGE plpgsql;
     
    CREATE TRIGGER trig_del BEFORE DELETE ON public."Consulta" 
    FOR EACH ROW EXECUTE PROCEDURE del_consulta();
    seulement lors de la suppression

    je reçois le message suivant :
    Exception in thread "main" org.postgresql.util.PSQLException: ERROR: falta una entrada para la tabla «Consulta» en la cláusula FROM
    Where: PL/pgSQL function "del_consulta" line 2 at sentencia SQL
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:353)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:299)
    at Code.Consulta.delete(Consulta.java:349)
    at Code.test.main(test.java:22)
    Java Result: 1
    ma fonction java est la suivante :
    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
    public boolean delete() throws ClassNotFoundException, SQLException{
            boolean b = false;
            BaseDonnees bd = new BaseDonnees();
            bd.connect();
            int i = 0;
            String req = "DELETE FROM public.\"Consulta\" WHERE public.\"Consulta\".\"idConsulta\" = "+this.id+";";
            i = bd.s.executeUpdate(req);
            if (i!=0){
                b = true;
            }
            System.out.println("effacer Consulta : "+i);
            bd.disconnect();
            return b;
     
        }
    je ne comprend pas ce qu'il me veut en me disant qu'il me manque une entrée pour ma table consulta

  4. #4
    Membre du Club
    Inscrit en
    Juin 2009
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 64
    Points : 42
    Points
    42
    Par défaut
    j'ai trouvé sur http://www.postgresql.org/docs/7.4/s...-appendix.html
    que l'erreur 42P01 correspondait à une table indéfinie :s
    ça ne m'avance pas beaucoup
    je dois avoir un problème dans mon delete mais je ne vois pas quoi

  5. #5
    Membre émérite
    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
    Points : 2 890
    Points
    2 890
    Par défaut
    En schématisant, tu a écris quelque chose de cette forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DELETE FROM table2 WHERE table2.colonne2=table1.colonne1;
    Or ce n'est pas valide car l'interpréteur SQL ne peut pas savoir de quelle ligne de table1 il s'agit quand il voit table1.colonne1.
    Ce que tu veux probablement, c'est ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DELETE FROM table2 WHERE table2.colonne2=OLD.colonne1;
    sachant que OLD dans un trigger DELETE est un alias qui désigne justement la ligne qui va être supprimée.

    A noter aussi qu'il y la clause ON DELETE CASCADE qui est possible dans une déclaration de clef étrangère et qui fait automatiquement ce travail pour toi.

  6. #6
    Membre du Club
    Inscrit en
    Juin 2009
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 64
    Points : 42
    Points
    42
    Par défaut
    oui et non lol
    parce que quan je fait mon delete de consulta, je suis pas dans le trigger donc il ne supporte pas de old
    d'autre par this.id renvoi un integer donc la requete au final est vraiment toute bete il doit y avoir conflit entre le trigger et le delete

    ton "on delete cacasde" doit surement être ma solution
    seulement je savais pas à quoi ça servait jusqu'à maintenant
    je vais voir si j'arrive à la mettre en place.

    [EDIT] merciiii! ça fonctionne bien

  7. #7
    Membre émérite
    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
    Points : 2 890
    Points
    2 890
    Par défaut
    Citation Envoyé par Espinosa Voir le message
    parce que quan je fait mon delete de consulta, je suis pas dans le trigger donc il ne supporte pas de old
    Ce n'est pas dans le delete de consulta que je propose de mettre le OLD, mais c'est là où l'erreur se produit c'est-à-dire dans le trigger, et ça concernerait tous les DELETE du trigger car ils ont l'air d'avoir tous ce même problème.
    Par exemple pour le début ça donnerait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CREATE FUNCTION del_consulta() RETURNS TRIGGER AS
    $$
    BEGIN
     DELETE FROM public."Drogas" WHERE "idDrogas" = OLD."fkDrogas";
     etc...
    Aussi, peut-être que je n'ai pas compris ton intention mais en première approche j'ai l'impression que la logique est inversée.
    En effet quand T1.fk se réfère à T2.pk, on ne va pas effacer une ligne de T2 quand on efface la ligne de T1, c'est le contraire. C'est si on supprimait la ligne de T2 qu'il faudrait d'abord enlever celle de T1.

  8. #8
    Membre du Club
    Inscrit en
    Juin 2009
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 64
    Points : 42
    Points
    42
    Par défaut
    Aussi, peut-être que je n'ai pas compris ton intention mais en première approche j'ai l'impression que la logique est inversée.
    En effet quand T1.fk se réfère à T2.pk, on ne va pas effacer une ligne de T2 quand on efface la ligne de T1, c'est le contraire. C'est si on supprimait la ligne de T2 qu'il faudrait d'abord enlever celle de T1.
    c'était mon premier essaie mes postgresql m'a gentillement répondu que je ne pouvais pas
    donc j'me suis dis, j'vais supprimé la ligne correspondant dans drogas
    puis après je serais tranquille pour supprimer consulta

    m'enfin,
    j'ai bien mis les on cascade delete
    malheureusement ça n'a pas l'air de supprimer grand chose
    ça me supprime consulta mais pas drogas... >_<

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CONSTRAINT "fkPersonna" FOREIGN KEY ("fkIdPersona")
          REFERENCES "Personna" ("idPersonna") MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE CASCADE

  9. #9
    Membre émérite
    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
    Points : 2 890
    Points
    2 890
    Par défaut
    CONSTRAINT "fkPersonna" FOREIGN KEY ("fkIdPersona")
    REFERENCES "Personna" ("idPersonna") MATCH SIMPLE
    ON UPDATE NO ACTION ON DELETE CASCADE
    Si fkPersonna est un champ de la table consulta, alors il est normal qu'effaçer dans consulta n'effaçe rien dans Personna.
    Par contre le fait d'effaçer dans Personna effaçera automatiquement les lignes correspondantes dans consulta.

  10. #10
    Membre du Club
    Inscrit en
    Juin 2009
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 64
    Points : 42
    Points
    42
    Par défaut
    en effet
    merci!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. trigger pour supprimer les lignes d'une table
    Par gilles_906 dans le forum Requêtes
    Réponses: 11
    Dernier message: 15/12/2012, 15h54
  2. Réponses: 1
    Dernier message: 01/05/2011, 20h36
  3. trigger pour supprimer une ligne
    Par hammag dans le forum SQL
    Réponses: 3
    Dernier message: 07/06/2010, 15h32
  4. Trigger pour faire une table "mirroir"
    Par lgomez dans le forum Oracle
    Réponses: 8
    Dernier message: 26/10/2005, 13h12
  5. supprimer une clé étrangère
    Par popopopo dans le forum Langage SQL
    Réponses: 5
    Dernier message: 04/08/2005, 10h34

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