CREATE RULE — Définir une nouvelle règle de réécriture
CREATE [ OR REPLACE ] RULEnom
AS ONévénement
TOnom_table
[ WHEREcondition
] DO [ ALSO | INSTEAD ] { NOTHING |commande
| (commande
;commande
... ) } oùévénement
fait partie de : SELECT | INSERT | UPDATE | DELETE
CREATE RULE
définit une nouvelle règle sur une
table ou une vue. CREATE OR REPLACE RULE
crée une nouvelle
règle ou remplace la règle si elle existe déjà.
Le système de règles de PostgreSQL autorise la
définition d'actions alternatives sur les insertions, mises à jour
ou suppressions dans les tables.
Pour résumer, une règle impose des commandes supplémentaires lors de l'exécution
d'une instruction sur une table donnée.
Une règle INSTEAD
, au contraire, permet de remplacer une commande
par une autre, voire d'empêcher sa réalisation.
Ce sont également les règles qui sont utilisées pour implanter les vues.
Une règle est un mécanisme de transformation de commandes, une « macro ». La transformation intervient avant l'exécution de la commande. Pour obtenir une opération qui s'exécute indépendamment pour chaque ligne physique, il faut utiliser des déclencheurs. On trouvera plus d'informations sur le système des règles dans Chapitre 40.
À l'heure actuelle, les règles ON SELECT
doivent être des règles
INSTEAD
inconditionnelles. Chacune de leurs actions ne peut être constituée
que d'une simple commande SELECT
.
Ainsi, une règle ON SELECT
a pour résultat la transformation
effective d'une table en une vue dont le contenu visible est composé
des lignes retournées par la commande SELECT
de la règle ;
ce ne sont pas les lignes stockées dans la table (s'il y en a) qui sont retournées.
Le création d'une vue à l'aide de la commande
CREATE VIEW
est toujours préférable à la création d'une table réelle
associée à une règle ON SELECT
.
On peut donner l'illusion d'une vue actualisable (« updatable view »)
par la définition de règles ON INSERT
,
ON UPDATE
et ON DELETE
(ou tout sous-ensemble de
celles-ci) pour remplacer les actions de mises à jour
de la vue par des mises à jours des tables adéquates. Si vous voulez supporter
INSERT RETURNING
, alors assurez-vous de placer une clause
RETURNING
adéquate à chacune de ces règles.
Il y a quelques chausse-trappes à éviter lors de l'utilisation de
règles conditionnelles pour la mise à jour de vues complexes :
à chaque action autorisée sur la vue doit
correspondre une règle INSTEAD
inconditionnelle.
Si la règle est conditionnelle ou n'est pas une règle INSTEAD
,
alors le système rejette toute tentative de mise à jour, ceci afin d'éviter
toute action sur la table virtuelle de la vue.
Pour gérer tous les cas utiles à l'aide de règles conditionnelles, il convient
d'ajouter une règle inconditionnelle DO INSTEAD NOTHING
afin de préciser au système qu'il ne recevra jamais de demande
de mise à jour d'une table virtuelle. La clause INSTEAD
des règles conditionnelles peut alors être supprimée ;dans les cas
où ces règles s'appliquent, l'action INSTEAD NOTHING
est utilisée. (Néanmoins, cette méthode ne fonctionne pas actuellement avec les
requêtes RETURNING
.)
Une vue qui est suffisamment simple pour être modifiable automatiquement (voir CREATE VIEW) ne nécessite pas un règle utilisateur pour être modifiable. Bien que vous puissiez de toute façon créer une règle, la transformation automatique de la mise à jour sera généralement plus performante qu'une règle explicite.
Une autre alternative à considérer est l'utilisateur des triggers
INSTEAD OF
(voir CREATE TRIGGER) à
la place des règles.
nom
Le nom de la règle à créer. Elle doit être distincte du nom de toute autre règle sur la même table. Les règles multiples sur la même table et le même type d'événement sont appliquées dans l'ordre alphabétique des noms.
événement
SELECT
, INSERT
,
UPDATE
ou DELETE
. Notez qu'un
INSERT
contenant une clause ON
CONFLICT
nepeut pas être utilisé sur des tables ayant une
règle INSERT
ou UPDATE
. Utilisez
plutôt une vue modifiable automatiquement.
nom_table
Le nom (éventuellement qualifié du nom du schéma) de la table ou de la vue sur laquelle s'applique la règle.
condition
Toute expression SQL conditionnelle (renvoyant un type
boolean
). L'expression de la condition ne peut pas
faire référence à une table autre que NEW
ou
OLD
ni contenir de fonction d'agrégat.
INSTEAD
Les commandes sont exécutées à la place de la commande originale.
ALSO
Les commandes sont exécutées en plus de la commande originale.
En l'absence de ALSO
et de INSTEAD
,
ALSO
est utilisé par défaut.
commande
Commande(s) réalisant l'action de la règle. Les commandes valides
sont SELECT
, INSERT
,
UPDATE
, DELETE
ou
NOTIFY
.
À l'intérieur d'une condition
ou d'une commande
, les noms des
tables spéciales NEW
et OLD
peuvent
être utilisés pour faire référence aux valeurs de la table référencée.
NEW
peut être utilisé dans les règles ON
INSERT
et ON UPDATE
pour faire
référence à la nouvelle ligne lors d'une insertion
ou à la nouvelle valeur de la ligne lors d'une mise à jour. OLD
est
utilisé dans les règles ON UPDATE
et ON
DELETE
pour référencer la ligne existant avant modification
ou suppression.
Vous devez être le propriétaire de la table à créer ou sur laquelle vous ajoutez des règles.
Dans une règle pour l'action INSERT
, UPDATE
ou DELETE
sur une vue, vous pouvez ajouter une clause
RETURNING
qui émet les colonnes de la vue. Cette clause
sera utilisée pour calculer les sorties si la règle est déclenchée
respectivement par une commande INSERT RETURNING
,
UPDATE RETURNING
ou DELETE RETURNING
.
Quand la règle est déclenchée par une commande sans clause
RETURNING
, la clause RETURNING
de la
règle est ignorée. L'implémentation actuelle autorise seulement des règles
INSTEAD
sans condition pour contenir
RETURNING
; de plus, il peut y avoir au plus une
clause RETURNING
parmi toutes les règles pour le même
événement. (Ceci nous assure qu'il y a seulement une clause
RETURNING
candidate utilisée pour calculer les résultats.)
Les requêtes RETURNING
sur la vue seront rejetées s'il
n'existe pas de clause RETURNING
dans une des règles
disponibles.
Une attention particulière doit être portée aux règles circulaires.
Ainsi dans l'exemple suivant, bien que chacune des deux définitions de règles
soit acceptée par PostgreSQL, la commande SELECT
produira une erreur à cause de l'expansion récursive de la règle :
CREATE RULE "_RETURN" AS ON SELECT TO t1 DO INSTEAD SELECT * FROM t2; CREATE RULE "_RETURN" AS ON SELECT TO t2 DO INSTEAD SELECT * FROM t1; SELECT * FROM t1;
Actuellement, si l'action d'une règle contient une commande
NOTIFY
, cette commande est exécutée sans condition,
c'est-à-dire que NOTIFY
est déclenché même si la règle
ne s'applique à aucune ligne. Par exemple, dans :
CREATE RULE notify_me AS ON UPDATE TO matable DO ALSO NOTIFY matable; UPDATE matable SET name = 'foo' WHERE id = 42;
un événement NOTIFY
est lancé durant un
UPDATE
, qu'il y ait ou non des lignes satisfaisant la
condition id = 42
. Cette restriction
pourrait être corrigée dans les prochaines versions.
CREATE RULE
est une extension
PostgreSQL, tout comme l'est le système
complet de réécriture de requêtes.