PostgreSQL
La base de données la plus sophistiquée au monde.

Ouverture de session

Navigation

Contactez-nous

Administration du site :
"equipe chez postgresqlfr point org"

Contact presse :
"fr chez postgresql point org"

Contact association :
"bureau chez postgresqlfr point org"

Questions PostgreSQL :
 IRC :
  serveur irc.freenode.net
  canal #postgresqlfr

Recherche

Accéder aux archives

« Octobre 2008  
Lun Mar Mer Jeu Ven Sam Dim
  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  

Syndication

Flux XML

Sondage

Quelle est la version de PostgreSQL la plus répandue sur vos serveurs ?
8.3
10%
8.2
42%
8.1
40%
8.0
2%
7.4
6%
7.3 ou antérieure
0%
Nombre de votes: 48

Fonctionnement des RULE(S)

Technique - général | Fonctionnement des RULE(S)

Par farphadet le 05/09/2007 - 21:20

Bonjour,

Voila j'ai 3 tables et une vue. La vue est une résultante de ces 3 tables. Ce que je veux faire c'est pouvoir faire les opérations de base SELECT, INSERT, UPDATE, DELETE sur la vue et que ces opérations soit répercuter sur les différentes tables. Pour cela j'ai donc définit des REGLES pour l'INSERT, l'UPDATE et le DELETE. Tout fonctionnement bien pour l'INSERT et pour l'UPDATE, mais malheureusement la RULE pour le DELETE ne fonctionne pas comme je le voudrais. Je ne vais pas vous donnez la RULE qui me serait utile de connaitre, mais celle qui me fait me poser beaucoup de questions sur le fonctionnement des RULES.

Voici les 3 tables :

urls:
 
 Column | Type | Modifiers
--------+-------------------+---------------------------------------------------
 id | integer | not null default nextval('urls_id_seq'::regclass)
 note | integer |
 url | character varying |
 forbid | integer |
 utype | character varying |
 status | character varying |
Indexes:
    "urls_pkey" PRIMARY KEY, btree (id)

urls_lists:

Column | Type | Modifiers
---------+---------+-----------
url_id | integer | not null
list_id | integer | not null
forbid | integer |
Indexes:
"urls_lists_pkey" PRIMARY KEY, btree (url_id, list_id)
Foreign-key constraints:
"urls_lists_list_id_fkey" FOREIGN KEY (list_id) REFERENCES lists(id)
"urls_lists_url_id_fkey" FOREIGN KEY (url_id) REFERENCES urls(id)

lists:

Column | Type | Modifiers
--------+-------------------+----------------------------------------------------
id | integer | not null default nextval('lists_id_seq'::regclass)
name | character varying |
code | character varying |
descpt | character varying |
Indexes:
"lists_pkey" PRIMARY KEY, btree (id)

Voici la vue avec la RULE ON DELETE TO:

View "public.urls_view"
Column | Type | Modifiers
---------+-------------------+-----------
url_id | integer |
list_id | integer |
code | character varying |
utype | character varying |
url | character varying |
forbid | integer |
View definition:
SELECT urls_lists.url_id, urls_lists.list_id, lists.code, urls.utype, urls.url, urls_lists.forbid
FROM urls
LEFT JOIN urls_lists ON urls_lists.url_id = urls.id
LEFT JOIN lists ON urls_lists.list_id = lists.id;
Rules:
delete_urls_view AS
ON DELETE TO urls_view DO INSTEAD ( DELETE FROM urls_lists
WHERE urls_lists.url_id = 1000;
DELETE FROM urls_lists
WHERE urls_lists.url_id = 100;
)

La RULE ON DELETE TO est inutile mais elle sert juste d'exemple.

Donc lorsque je fais un :

DELETE FROM urls_view;

La RULE est executé integralement et les enregistrement correspondant à l'url_id 100
et 1000 sont bien supprimés.

Lorsque je fais :

DELETE FROM urls_view WHERE url_id = 1000;

Seul la premiere commande SQL de la RULE est éxecutée. Et donc seul l'enregsitrement
corréspondant à l'url_id 1000 est supprimé.

Lorsque je fais :

DELETE FROM url_view WHERE url_id = 100;

La RULE est éxécuté integralement.

Je ne comprends vraiment pas ce fonctionnement. Quelqu'un aurait-il une réponse clair
et compléte, ainsi que certaine sur le fonctionnement de cette RULE.

Merci pour votre aide

Options d'affichage des commentaires

Sélectionnez la méthode d'affichage des commentaires que vous préférez, puis cliquez sur "Sauvegarder les paramètres" pour activer vos changements.

up

farphadet/ = 17 Septembre, 2007 - 10:15

up


ben oui, il réagit au 'ON DE

sparky/ = 17 Septembre, 2007 - 10:31

ben oui, il réagit au 'ON DELETE ' donc quand tu demandes un effacement, les 2 commandes devraient être exécutés. Ton problème est quand tu fais "DELETE FROM urls_view WHERE url_id = 1000;" normalement la rule devraient être éxécutés intégralement. P-e un lock qui stoppe l'éxécution. Le mieux est de changer les options de postgres et d'ajouter du log puis de voir dans les logs ce qui se passe.
Au fait il s'agit d'une régle 'DO INSTEAD' ou 'DO ALSO' ??? A mon avis tu devrais utiliser DO INSTEAD


Il s'agit bien d'un DO INSTEA

farphadet/ = 18 Septembre, 2007 - 11:22

Il s'agit bien d'un DO INSTEAD. Ces différent comportement sont vraiment bizarre. N'yaurait-il personne ayant une éxplication logique ou peut-être est-ce un bud de postgresql.


as-tu regarder dans les logs

sparky/ = 19 Septembre, 2007 - 17:46

as-tu regarder dans les logs de postgres ??


de retour d'un long sejour ,

farphadet/ = 14 Novembre, 2007 - 18:20

de retour d'un long sejour , quelqu'un aurait-il une réponse à ma question


Simple.. et complexe

Jean-Paul Argudo/ = 15 Novembre, 2007 - 11:20

Bonjour farphadet,

Vous êtes tombés sur un problème connu, dont la solution est simple, mais la raison un peu plus complexe.

Pour faire simple, votre écriture des RULES n'est pas bonne.

Vous devez faire comme suit pour la partie entre paranthèse, sur le DELETE:

DELETE FROM urls_lists WHERE urls_lists.url_id = old.urls_lists.url_id

La raison est expliquée en détails ici:

http://docs.postgresqlfr.org/8.2/rules-update.html
.

Je vous suggère de lire d'ailleurs le chapitre 35 tout entier..

Une fois la rule modifiée, vous pourrez écrire vos deletes sur la vue avec where = ce que vous voulez, et vous devriez avoir le comportement attendu.

Attention toutefois à ne pas tomber ensuite dans le cas décrit ici:

http://www.varlena.com/GeneralBits/68.php
("Rules and views and cascading deletes"), qui est un problème tout aussi connu :-)

--
Jean-Paul ARGUDO
http://dalibo.com | http://dalibo.org


© PostgreSQLFr, tous droits réservés.
Site déclaré à la CNIL sous le numéro 1074678, conformément à la Loi en vigueur.