Précédent   Forum des professionnels en informatique > Bases de données > PostgreSQL
PostgreSQL Forum PostgreSQL. Avant de poster -> F.A.Q PostGreSQL Tutoriels PostGreSQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 18/05/2004, 09h14   #1
Membre actif
 
Inscription : juin 2003
Messages : 209
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 209
Points : 189
Points : 189
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 :
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 :
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 :
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 :
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?
Bouboubou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2004, 10h12   #2
Membre confirmé
 
Inscription : octobre 2003
Messages : 266
Détails du profil
Informations forums :
Inscription : octobre 2003
Messages : 266
Points : 287
Points : 287
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 ???

@+
Krapulax est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2004, 12h38   #3
Membre actif
 
Inscription : juin 2003
Messages : 209
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 209
Points : 189
Points : 189
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+
Bouboubou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2004, 14h41   #4
Membre actif
 
Inscription : juin 2003
Messages : 209
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 209
Points : 189
Points : 189
Est-ce un bug de Postgres?!? Car selon l'aide, on peut écrire pls requêtes dans la zone d'action:

Code :
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 ... ]
Bouboubou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2004, 15h00   #5
Membre confirmé
 
Inscription : octobre 2003
Messages : 266
Détails du profil
Informations forums :
Inscription : octobre 2003
Messages : 266
Points : 287
Points : 287
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
Krapulax est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2004, 15h25   #6
Membre actif
 
Inscription : juin 2003
Messages : 209
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 209
Points : 189
Points : 189
Cette fois-ci Krapulax, c'est à moi de car j'ai mal interpréter l'aide de postgres: il disait:

Code :
[...]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 :
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]
Bouboubou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2004, 15h48   #7
Membre actif
 
Inscription : juin 2003
Messages : 209
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 209
Points : 189
Points : 189
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?
Bouboubou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2004, 17h13   #8
Membre confirmé
 
Inscription : octobre 2003
Messages : 266
Détails du profil
Informations forums :
Inscription : octobre 2003
Messages : 266
Points : 287
Points : 287
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.
Krapulax est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2004, 18h58   #9
Membre actif
 
Inscription : juin 2003
Messages : 209
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 209
Points : 189
Points : 189
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 :
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.
Bouboubou est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h55.


 
 
 
 
Partenaires

Hébergement Web