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 :

comment interdire la suppression d'une ligne


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Points : 42
    Points
    42
    Par défaut comment interdire la suppression d'une ligne
    bonjour,
    J'ai un soucis sur la suppression d'une ligne dans une table (T1).
    J'ai mis une contrainte sur la clef étrangère d'une autre table (T2)
    mais quand je veux supprimer la ligne de la table T1 qui à une contrainte
    sur la table T2, j'y arrive alors que je devrai avoir un message pour
    dire que j'ai une contrainte d'intégrité. Chose bizarre c'est que quand
    je fait un update de la table T1 avec une clef qui n'est pas référencer
    dans la table T2 j'ai bien le message d'erreur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ALTER TABLE T1
      ADD CONSTRAINT c_t1_id_fk FOREIGN KEY (t1_id)
          REFERENCES T2 (t2_id) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE NO ACTION;
    Y a t'il un paramètre de session sur postgres qui desactive les contraintes
    lors d'un delete?

  2. #2
    Expert éminent Avatar de kain_tn
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 629
    Points : 7 595
    Points
    7 595
    Par défaut
    Bonjour.

    Citation Envoyé par sth56 Voir le message
    bonjour,
    J'ai un soucis sur la suppression d'une ligne dans une table (T1).
    J'ai mis une contrainte sur la clef étrangère d'une autre table (T2)
    mais quand je veux supprimer la ligne de la table T1 qui à une contrainte
    sur la table T2, j'y arrive alors que je devrai avoir un message pour
    dire que j'ai une contrainte d'intégrité.
    Non c'est l'inverse:

    ta clé étrangère t'empêche de saisir une ligne dans T1 avec une valeur qui n'existe pas dans T2, et d'effacer une valeur dans T2 si la valeur est référencée dans T1.

    En revanche, si tu veux un comportement particulier sur un DELETE, tu peux essayer de créer une règle ou un trigger:
    http://www.postgresql.org/docs/8.3/s...reaterule.html

    http://www.postgresql.org/docs/8.3/s...tetrigger.html

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Points : 42
    Points
    42
    Par défaut
    Citation Envoyé par kain_tn Voir le message
    Bonjour.



    Non c'est l'inverse:

    ta clé étrangère t'empêche de saisir une ligne dans T1 avec une valeur qui n'existe pas dans T2, et d'effacer une valeur dans T2 si la valeur est référencée dans T1.
    comment on fait alors pour empêcher d'effacer une ligne dans T1 si elle est
    référencer dans T2? (je croyait que la clef étrangère gérais ça)

  4. #4
    Expert éminent Avatar de kain_tn
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 629
    Points : 7 595
    Points
    7 595
    Par défaut
    Citation Envoyé par sth56 Voir le message
    comment on fait alors pour empêcher d'effacer une ligne dans T1 si elle est
    référencer dans T2? (je croyait que la clef étrangère gérais ça)
    Le truc, c'est qu'à cause (grace à) ta clé étrangère, une ligne dans T1 est forcément référencée dans T2.
    En revanche, toutes les valeurs de T2 ne sont pas forcément présentes dans T1:


    ex:
    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
     
                utilisateur                                  genre
     --------------------                  -----------------------
    |ID_PK               |     |--------> |ID_PK                  |
    |LOGIN               |     |          |GENRE                  |
    |GENRE_ID_FK         | ----|          |                       |
     --------------------                 ------------------------
     
     
    INSERT INTO genre ("GENRE") VALUES('male');
    INSERT INTO genre ("GENRE") VALUES('female');
     
    INSERT INTO utilisateur ("LOGIN", "GENRE_ID_FK") VALUES('toto', 1);
    INSERT INTO utilisateur ("LOGIN", "GENRE_ID_FK") VALUES('tata', 2);
    INSERT INTO utilisateur ("LOGIN", "GENRE_ID_FK") VALUES('tutu', 2);
    INSERT INTO utilisateur ("LOGIN", "GENRE_ID_FK") VALUES('E.T.', 3);
    La dernière ligne ne fonctionnera pas car la valeur '3' n'est pas référencée.
    Cela évite ainsi de rentrer n'importe quoi dans ta table.
    Mais rien ne t'empêche de supprimer l'utilisatrice 'tutu' de ta base, alors que son genre est référencé.
    De même, essayer de supprimer le genre 'male' de la table genre conduira à une erreur car genre est référencée par une ligne dans utilisateur.

    Donc finalement, comme tu ne peux pas supprimer une valeur de genre référencée dans utilisateur (tu as mis DELETE NO ACTION plutôt que cascade), tu peux vouloir empêcher tous les DELETE sur utilisateur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CREATE RULE pas_de_deletes AS ON DELETE
    	TO utilisateur
    	DO INSTEAD NOTHING;

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 43
    Points : 42
    Points
    42
    Par défaut
    merci pour tes explication kain_tn le fonctionnement des clef étrangères
    es plus clair, la creation de rule va me permettre d'éviter d'effacer mes
    tables me reste à voir si je peux rajouter des conditions et si je peux
    envoyer un message d'erreur si les conditions sont pas respecter.

  6. #6
    Expert éminent Avatar de kain_tn
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 629
    Points : 7 595
    Points
    7 595
    Par défaut
    Oui tu peux:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    CREATE RULE pas_de_deletes AS ON DELETE
    	TO utilisateur WHERE tes_conditions
    	DO INSTEAD la_ou_les_requete(s)_que_tu_veux_a_la_place;
     
    CREATE RULE pas_de_deletes AS ON DELETE
    	TO utilisateur WHERE genre > 2
    	DO INSTEAD SELECT 'Genre inconnu!!!';

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

Discussions similaires

  1. [XL-2007] Comment interdire la suppression d'une feuille ?
    Par mobiclick dans le forum Macros et VBA Excel
    Réponses: 19
    Dernier message: 01/07/2009, 08h37
  2. Comment Interdire la suppression d'une base mdb ?
    Par abdelo78 dans le forum Sécurité
    Réponses: 1
    Dernier message: 19/02/2007, 08h52
  3. Interdire la suppression d'une ligne dans une BDD
    Par griese dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 30/06/2006, 10h32
  4. Comment interdire la fermeture d'une fiche empilée ?
    Par psau dans le forum C++Builder
    Réponses: 3
    Dernier message: 05/07/2004, 14h01
  5. Réponses: 6
    Dernier message: 04/03/2004, 09h35

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