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

PostgreSQL Discussion :

delete sur une vue: rule


Sujet :

PostgreSQL

  1. #1
    Membre actif

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2003
    Messages : 209
    Points : 249
    Points
    249
    Par défaut delete sur une vue: rule
    Salut,

    Je souhaite créer une vue sur deux tables puis pouvoir effectuer des update, insert, delete et select sur cette vue.

    J'ai créé ma vue:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    create view vue1 as
    select c.id, c.version, pe.idor
    from table1 c, table2 pe
    where c.id = pe.idor;//il y a un héritage derrière...
    Puis il m'a fallut faire les rules correspondant:

    insert:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    create or replace rule rivue1 
    as on insert to vue1
    do instead 
    (
        insert into table1 (id,version) 
        values (new.id,new.version);
        insert into table2 (idcol,idor)
        values (new.id,new.idor)
    );
    delete:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    create or replace rule rdvvue1
    as on delete to vue1
    do instead 
    (
        delete from table2 
        where idcol = old.id;
        delete from table1 
        where id = old.id  
    );
    update
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    create or replace rule ruvue1 
    as on update to vue1 
    do instead 
    (
        update table1
        set id = new.id, version = new.version
        where id = old.id;
        update table2
        set idcol = new.id, idor = new.idor
        where idcollection = old.id
    );
    Alors il est possible de faire des select sans problème. L'insert se passe également correctement mais par contre dès que j'essaye de faire un delete, les enregistrements de ma première table sont supprimés mais pas dans ma deuxième table!

    Je ne comprends pas... je tourne en rond en faisant plein de tests mais sans succès! Qqun aurait une idée?

  2. #2
    Membre averti
    Inscrit en
    Octobre 2003
    Messages
    266
    Détails du profil
    Informations forums :
    Inscription : Octobre 2003
    Messages : 266
    Points : 318
    Points
    318
    Par défaut
    Salut,

    Juste une idée comme ça, du fait de l'héritage (ou d'une contrainte que je connais pas...), ne dois-tu pas d'abord faire un delete sur la table1 puis sur la table2 ???

    @+

  3. #3
    Membre actif

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2003
    Messages : 209
    Points : 249
    Points
    249
    Par défaut
    Salut Krapulax,

    Cela fait plaisir de te revoir...

    J'y ai pensé.... j'ai testé cela sans les contraintes d'intégrités. Si j'inverse l'ordre des deletes dans le do instead. Il me fait tjs le premier mais jamais le deuxième!

    Pfff... je ne sais plus quoi faire...

    A+

  4. #4
    Membre actif

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2003
    Messages : 209
    Points : 249
    Points
    249
    Par défaut
    Est-ce un bug de Postgres?!? Car selon l'aide, on peut écrire pls requêtes dans la zone d'action:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    CREATE RULE name AS ON event
        TO object [ WHERE condition ]
        DO [ INSTEAD ] action
     
    where action can be:
     
    NOTHING
    |
    query
    |
    ( query ; query ... )
    |
    [ query ; query ... ]

  5. #5
    Membre averti
    Inscrit en
    Octobre 2003
    Messages
    266
    Détails du profil
    Informations forums :
    Inscription : Octobre 2003
    Messages : 266
    Points : 318
    Points
    318
    Par défaut
    J'ai regardé un peu à gauche et à droite.... j'ai quelques pistes.

    Quand tu parles d'héritage, est-ce vraiment au sens objet du terme (CREATE TABLE.... INHERITS table), ou est-ce plutôt une clé ou une contrainte ?

    Si j'ai bien compris la doc (CREATE TABLE chapitre INHERITS), il gère l'héritage comme une contrainte. Si c'est vrai, regardes du côté des ON DELETE CASCADE

    cf newsgroup : http://minilien.com/?wES1i0Stre

  6. #6
    Membre actif

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2003
    Messages : 209
    Points : 249
    Points
    249
    Par défaut
    Cette fois-ci Krapulax, c'est à moi de car j'ai mal interpréter l'aide de postgres: il disait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [...]Il y a un problème si vous essayez d'utiliser les règles conditionnelles pour les mises à jour de vues; une règle INSTEAD doit être inconditionnelle pour chaque action que vous voulez permettre sur la vue. Si la règle est conditionnelle, ou n'est pas INSTEAD, le système rejettera encore les tentatives d'exécution de mise à jour, car il croit qu'il peut pour finir tenter d'exécuter l'action sur la table fictive dans certains cas. Si vous voulez manipuler tous les cas possibles de règles conditionnelles, vous pouvez; ajoutez juste une règle DO INSTEAD NOTHING pour vous assurer que le système comprenne qu'il ne sera jamais appelé sur des mises à jour de tables fictives. Ensuite, faites une règle conditionnelle non-INSTEAD.[...]
    Hors je pensais que la condition était la clause facultative condition dans le create rule et pas dans le delete. Donc il faut faire un create rule sans le mot clé instead et ensuite en refaire un avec le instead et nothing dans la clause action:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    create or replace rule rdvprogramme 
    as on delete to vprogramme 
    do
    (
        delete from programmeenseignement 
        where idcollection = old.id;
        delete from collection 
        where id = old.id
    );
    create or replace rule rdvprogramme 
    as on delete to vprogramme 
    do instead nothing;
    Maintenant cela joue... Merci merci merci... car j'avais regardé dans les bugs et TODO liste de Postgres. Ils vont d'ailleurs créer automatiquement les rules pour les vues dans les prochaines versions.[/i]

  7. #7
    Membre actif

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2003
    Messages : 209
    Points : 249
    Points
    249
    Par défaut
    Pffff.... non non non... cela ne fonctionne tjs pas! Je me suis emballé! J'ai bien cru que c'était bon, mais tjs le même problème!

    Pour répondre à ta précédente question, Krapulax, je n'utilise pas le vrai inherits de postgres, c'est un héritage dans lequel, j'utilise juste la clé primaire du parent. Car cela me permets d'avoir plus types d'enfant pour un parent donné. Ce que ne permet pas de faire le inhérits. Mais en fait, pour l'instant je fais des tests sans contraintes d'intégrité! Donc de ce côté là, je ne devrais pas avoir de problème.

    Encore une autre idée?

  8. #8
    Membre averti
    Inscrit en
    Octobre 2003
    Messages
    266
    Détails du profil
    Informations forums :
    Inscription : Octobre 2003
    Messages : 266
    Points : 318
    Points
    318
    Par défaut
    Si tu utilises comme contrainte (comme je pensais), regardes bien le post que je t'avais mis en lien : la personne avait l'air d'être dans le même cas que toi.

  9. #9
    Membre actif

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2003
    Messages : 209
    Points : 249
    Points
    249
    Par défaut
    Hello,

    Oui j'ai lu ton lien... le truc c'est que eux ils parlent bcp de problème de référence entre les tables. Pour ma part, je n'ai pas de contrainte d'intégrité... donc normalement pas de problème! Leur solution c'est de faire une fonction stockée... Pfff... je trouve cette solution relativement lourde. J'ai encore fait des tests, tu peux sans autre copier l'exemple et l'exécuter:

    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
    create table a (id integer);
    create table b (id integer);
    create view ab as select a.id as ida, b.id as idb from a, b where a.id = b.id;
    create rule riab as on insert to ab do instead (insert into a values (new.ida);insert into b values (new.idb););
    insert into ab values (2,2);
    select * from ab;
    create rule rdab as on delete to ab do (delete from a where id = old.ida; delete from b where id = old.idb;);
    create rule rdnab as on delete to ab do instead nothing;
    delete from ab where ida = 2;
    select * from ab;
    select * from a;
    select * from b;
    /*drop view ab;*/
    /*drop table a;*/
    /*drop table b;*/
    Résultat: Il reste un enregistrement dans la table b! La table a est vide.

    Le truc, c'est cela ne fonctionne pas. Si la doc de postgres dit que c'est possible de faire pls action par règle, je ne vois pas pourquoi cela n'est pas possible. C'est donc un bug!?!?

    Désolé d'être un peu têtu, mais j'aime bien chercher de belle solution... car par expérience, je sais que si je fais une solution qui n'est pas propre (fonction stockée), je vais avoir des problèmes plus loin.

    Merci de ton aide... Si tu as encore une idée, c'est volontier.

    P.S: Peux-tu juste tester le bout de code et me dire si tu as la même chose... Merci d'avance.

Discussions similaires

  1. Delete sur une vue 2008 => 2008 R2
    Par toto9o dans le forum Développement
    Réponses: 3
    Dernier message: 08/09/2011, 11h00
  2. [MFC] Créer une multitude d'infos bulles sur une vue
    Par Philippe320 dans le forum MFC
    Réponses: 2
    Dernier message: 03/02/2006, 10h57
  3. [Trigger] Comment le réaliser sur une vue ?
    Par mandale dans le forum DB2
    Réponses: 1
    Dernier message: 19/09/2005, 13h43
  4. Comment avoir une référence sur une Vue
    Par Philippe299 dans le forum MFC
    Réponses: 1
    Dernier message: 12/08/2005, 10h03
  5. Temps d'execution d'un select sur une vue
    Par rosewood dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 21/02/2005, 16h06

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