CREATE RULE

Name

CREATE RULE  --  Definit une nouvelle règle.

Synopsis

CREATE RULE name AS ON event
    TO object [ WHERE condition ]
    DO [ INSTEAD ] action

where action can be:

NOTHING
|
query
|
( query ; query ... )
|
[ query ; query ... ]
  

Entrées

name

nom de la règle a créer.

event

Eventfait partie des SELECT, UPDATE, DELETE ou INSERT.

object

Object est soit table ou table.column. (Actuellement, seule la forme table implémentée).

condition

Certaines expressions conditionnelles-booléennes SQL. L'expression conditionnelle ne doit pas se référer aux tables sauf new et old.

query

La ou les requêtes générant l'action peuvent être une clause SQL SELECT, INSERT, UPDATE, DELETE, ou NOTIFY.

Dans condition et action,les noms de tables spéciaux new et old peuvent être utilisés en référence aux valeurs dans la table référencée (le object). new est valide dans des règles ON INSERT et ON UPDATE en référence aux nouvelles lignes insérées ou mises à jour. old est valide dans des règles ON UPDATE et ON DELETE en référence aux lignes existantes mises à jour ou supprimées.

Sorties

CREATE

message retourné si la règle a été créée correctement.

Description

le système de règles de PostgreSQL permet de définir une action alternative à exécuter sur les insertions, mises à jour, ou suppressions des tables de la base. Les règles sont utilisées pour implémenter également des vues de table.

Les sémantiques d'une règle font qu'au moment où une instance individuelle (ligne) est accédée, mise à jour, insérée ou supprimée, il y a une ancienne instance (pour les sélections, mises à jour et suppressions) et une nouvelle instance (pour les insertions et les mises à jour). Toutesl es règles du type donné et de la cible objet donnée (table) sont examinées, dans un ordre non spécifié. Si la condition spécifiée dans la clause WHERE est vraie, la partie action de la règle est exécutée. L'action est faite à la place de la requête d'origine si INSTEAD est spécifié; sinon elle est faite après la requête d'origine dans le cas d'un ON INSERT, ou avant la requête d'origine dans le cas d'un ON UPDATE ou ON DELETE. Dans les deux condition et action, les valeurs des champs dans l'ancienne instance et/ou la nouvelle instance sont substituées en old.attribute-name et new.attribute-name.

La partie action de la règle peut consister en une ou plusieurs requêtes. Pour écrires des requêtes multiples, entourez les soit de parenthèses soit de crochets carrés. Certaines requêtes seront exécutées dans un ordre spécifié (bien qu'il n'y ait pas de garantie sur l'ordre d'exécution des diverses règles pour un objet). L'action peut aussi être NOTHING indiquant aucune action. Ainsi, une règle DO INSTEAD NOTHING supprime la requête d'origine dans l'exécution (quand sa condition est vraie); une règle DO NOTHING est inutile.

La partie action de la règle s'exécute avec la même commande et identifiant de transaction que la commande utilisateur qui provoque l'activation.

Règles et vues

Actuellement, les règles ON SELECT doivent être des règles inconditionnelles INSTEAD et doivent avoir des actions consistant en une seule requête SELECT. Ainsi, une règle ON SELECT changera l'objet de la table en une vue, dont les contenus visibles sont les lignes retournées par la règle de la requête SELECT puisqu'elles ont été stockées quelque part dans la table. Il est considéré d'un meilleur style d'écrire une commande CREATE VIEW que de créer une table réelle et de définir une règle ON SELECT pour celle-ci.

CREATE VIEW crée une table factice (sans stockage sous-jacent) et y associe une règle ON SELECT. Le système n'admet pas les les mises à jour d'une vue, car il sait qu'il n'y a pas là de véritable table. Vous pouvez créer l'illusion d'une vue qui puisse se mettre à jour en définissant des règles ON INSERT, ON UPDATE, et ON DELETE (ou n'importe quel sous-ensemble de celles qui sont nécessaires pour notre propos) pour remplacer les actions de mises à jour sur les vues par des mises à jour appropriées sur d'autres tables.

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.

Notes

Vous devez avoir une règle de définition d'accès à une table afin de définir une règle sur elle. Utilisez GRANT et REVOKE pour modifier les permissions.

Il est très important de faire attention d'éviter les règles circulaires. Par exemple, chacune des deux définitions de règles suivantes sont acceptées par PostgreSQL, la commande select provoquera un rapport d'erreur de la part de Postgres car les requêtes ont un cycle trop fréquent :

CREATE RULE "_RETemp" AS
    ON SELECT TO emp
    DO INSTEAD 
	SELECT * FROM toyemp;

CREATE RULE "_RETtoyemp" AS
    ON SELECT TO toyemp
    DO INSTEAD 
	SELECT * FROM emp;
Cette tentative de sélection depuis EMP provoque un rapport d'erreur de PostgreSQL car les requêtes ont un cycle trop fréquent :
SELECT * FROM emp;

Actuellement, si une règle contient une reqête NOTIFY, le NOTIFY sera exécuté inconditionnellement --- le NOTIFY sera renvoyé même s'il n'y a pas d'autres lignes que la règle à appliquer. Par exemple, dans

CREATE RULE notify_me AS ON UPDATE TO mytable DO NOTIFY mytable;

UPDATE mytable SET name = 'foo' WHERE id = 42;
      
un NOTIFY sera envoyé pendant l'UPDATE, qu'il en soit ainsi ou non il y d'autres lignes avec id = 42. Ceci est une restriction d'implémentation qui peut être fixée dans les prochaines versions.

Compatibilité

SQL92

CREATE RULE est une extension du langage PostgreSQL. Il n'y a pas de CREATE RULE en SQL92.