Documentation PostgreSQL 14.22 » Référence » Commandes SQL » CREATE RULE

Précédent | Niveau supérieur | Suivant
CREATE ROLE | Sommaire | CREATE SCHEMA

## CREATE RULE

CREATE RULE — Définir une nouvelle règle de réécriture

## Synopsis

    CREATE [ OR REPLACE ] RULE nom AS ON événement
        TO nom_table [ WHERE condition ]
        DO [ ALSO | INSTEAD ] { NOTHING | commande | ( commande ; commande ... ) }

    où événement fait partie de :

        SELECT | INSERT | UPDATE | DELETE

## Description

`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 41.

Actuellement, les règles `ON SELECT` peuvent seulement être attachées aux vues. (En attacher une à une table convertit la table en vue.) Une règle de ce type doit être nommée `"_RETURN"`, elle doit être une règle `INSTEAD` inconditionnel, et elle doit avoir une action qui consiste en une simple commande `SELECT`. Cette commande définit le contenu visible de la vue. (La vue elle-même est dans les faits une table simple sans stockage.) Une règle de ce type est un détail d'implémentation. Alors qu'une vue peut être redéfinie via `CREATE OR REPLACE RULE "_RETURN" AS ...`, il serait préférable d'utiliser `CREATE OR REPLACE VIEW`.

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`.)

### Note

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.

## Paramètres

`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.

## Notes

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.

## Compatibilité

`CREATE RULE` est une extension PostgreSQL, tout comme l'est le système complet de réécriture de requêtes.

## Voir aussi

ALTER RULE, DROP RULE