PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 12.18 » Langage SQL » Fonctions et opérateurs » Fonctions de manipulation de séquences

9.16. Fonctions de manipulation de séquences

Cette section décrit les fonctions opérant sur les objets de type séquence, aussi appelés générateurs de séquence (ou tout simplement séquences). Les séquences sont des tables spéciales, monolignes, créées avec la commande CREATE SEQUENCE. Les séquences sont habituellement utilisées pour générer des identifiants uniques de lignes d'une table. Les fonctions de séquence, listées dans le Tableau 9.50, fournissent des méthodes simples, et sûres en environnement multiutilisateurs, d'obtention de valeurs successives à partir d'objets séquence.

Tableau 9.50. Fonctions séquence

FonctionType de retourDescription
currval(regclass)bigintRenvoie la valeur la plus récemment obtenue avec nextval pour la séquence indiquée
lastval()bigintRenvoie la valeur la plus récemment obtenue avec nextval pour toute séquence
nextval(regclass)bigintIncrémente la séquence et renvoie la nouvelle valeur
setval(regclass, bigint)bigintPositionne la valeur courante de la séquence
setval(regclass, bigint, boolean)bigintPositionne la valeur courante de la séquence et le drapeau is_called

La séquence à traiter par l'appel d'une fonction de traitement de séquences est identifiée par un argument regclass, qui n'est autre que l'OID de la séquence dans le catalogue système pg_class. Il n'est toutefois pas nécessaire de se préoccuper de la recherche de cet OID, car le convertisseur de saisie du type de données regclass s'en charge. Il suffit d'écrire le nom de la séquence entre guillemets simples, de façon à le faire ressembler à un libellé. Pour obtenir une compatibilité avec la gestion des noms SQL ordinaires, la chaîne est convertie en minuscules, sauf si le nom de la séquence est entouré de guillemets doubles. Du coup :

nextval('foo')      opère sur la séquence foo
nextval('FOO')      opère sur la séquence foo
nextval('"Foo"')    opère sur la séquence Foo

Le nom de la séquence peut, au besoin, être qualifié du nom du schéma :

nextval('mon_schema.foo')     opère sur mon_schema.foo
nextval('"mon_schema".foo')   identique à ci-dessus
nextval('foo')                parcourt le chemin de recherche
pour trouver foo

Voir la Section 8.19 pour plus d'informations sur regclass.

Note

Avant la version 8.1 de PostgreSQL, les arguments des fonctions de traitement de séquences étaient du type text, et non regclass. De ce fait, les conversions précédemment décrites d'une chaîne de caractères en valeur OID se produisaient à chaque appel. Pour des raisons de compatibilité, cette fonctionnalité existe toujours. Mais, en interne, un transtypage implicite est effectué entre text et regclass avant l'appel de la fonction.

Lorsque l'argument d'une fonction de traitement de séquences est écrit comme une simple chaîne de caractères, il devient une constante de type regclass. Puisqu'il ne s'agit que d'un OID, il permet de suivre la séquence originelle même en cas de renommage, changement de schéma... Ce principe de « lien fort » est en général souhaitable lors de références à la séquence dans les vues et valeurs par défaut de colonnes. Un « lien faible » est généralement souhaité lorsque la référence à la séquence est résolue à l'exécution. Ce comportement peut être obtenu en forçant le stockage des constantes sous la forme de constantes text plutôt que regclass :

nextval('foo'::text)      foo est recherché à l'exécution

Le lien faible est le seul comportement accessible dans les versions de PostgreSQL antérieures à 8.1. Il peut donc être nécessaire de le conserver pour maintenir la sémantique d'anciennes applications.

L'argument d'une fonction de traitement de séquences peut être une expression ou une constante. S'il s'agit d'une expression textuelle, le transtypage implicite impose une recherche à l'exécution.

Les fonctions séquence disponibles sont :

nextval

Avance l'objet séquence à sa prochaine valeur et renvoie cette valeur. Ce fonctionnement est atomique : même si de multiples sessions exécutent nextval concurrentiellement, chacune obtient sans risque une valeur de séquence distincte.

Si un objet séquence a été créé avec les paramètres par défaut, les appels à nextval sur celui-ci renvoient des valeurs successives à partir de 1. D'autres comportements peuvent être obtenus en utilisant des paramètres spéciaux de la commande CREATE SEQUENCE ; voir la page de référence de la commande pour plus d'informations.

Cette fonction nécessite le privilège USAGE ou UPDATE sur la séquence.

currval

Renvoie la valeur la plus récemment retournée par nextval pour cette séquence dans la session courante. (Une erreur est rapportée si nextval n'a jamais été appelée pour cette séquence dans cette session.) Parce qu'elle renvoie une valeur locale à la session, la réponse est prévisible, que d'autres sessions aient exécuté ou non la fonction nextval après la session en cours.

Cette fonction nécessite le privilège USAGE ou SELECT sur la séquence.

lastval

Renvoie la valeur la plus récemment retournée par nextval dans la session courante. Cette fonction est identique à currval, sauf qu'au lieu de prendre le nom de la séquence comme argument, elle se réfère à la dernière séquence utilisée par nextval dans la session en cours. Si nextval n'a pas encore été appelée dans la session en cours, un appel à lastval produit une erreur.

Cette fonction nécessite le privilège USAGE ou SELECT sur la dernière séquence utilisée.

setval

Réinitialise la valeur du compteur de l'objet séquence. La forme avec deux paramètres initialise le champ last_value de la séquence à la valeur précisée et initialise le champ is_called à true, signifiant que le prochain nextval avance la séquence avant de renvoyer une valeur. La valeur renvoyée par currval est aussi configurée à la valeur indiquée. Dans la forme à trois paramètres, is_called peut être initialisé à true ou à false. true a le même effet que la forme à deux paramètres. Positionné à false, le prochain nextval retourne exactement la valeur indiquée et l'incrémentation de la séquence commence avec nextval suivant. De plus, la valeur indiquée par currval n'est pas modifiée dans ce cas. Par exemple,

SELECT setval('foo', 42);           Le nextval suivant retourne 43
SELECT setval('foo', 42, true);     Comme ci-dessus
SELECT setval('foo', 42, false);    Le nextval suivant retourne 42

Le résultat renvoyé par setval est la valeur du deuxième argument.

Cette fonction nécessite le privilège UPDATE sur la séquence.

Attention

Pour éviter le blocage de transactions concurrentes pour l'obtention de nombres provenant de la même séquence, la valeur obtenue par nextval n'est pas réclamée pour une ré-utilisation si la transaction appelante s'annule après coup. Ceci signifie que des annulations de transaction ou des crashs de bases de données peuvent avoir pour conséquence des trous dans la séquence des valeurs affectées. Ceci peut aussi survenir sans annulation de transaction. Par exemple, un INSERT avec une clause ON CONFLICT calculera la ligne à insérer, incluant tout appel nécessaire à nextval, avant de détecter un conflit qui causera la poursuite sur la règle ON CONFLICT. De ce fait, les objets séquences de PostgreSQL ne peuvent pas être utilisées pour obtenir des séquences « sans trou » .

De la même façon, les changements d'état de séquence réalisées par setval sont immédiatement visibles aux autres transactions, et ne sont pas annulées si la transaction appelante annule ses modifications.

Si l'instance s'arrête brutalement avant de valider une transaction ayant exécuté un appel à nextval ou setval, le changement d'état de la séquence pourrait ne pas arriver jusqu'au stockage permanent, donc l'état de la séquence n'est pas certain, uqil soit à sa valeur d'originie ou à sa nouvelle valeur après le redémarrage de l'instance. Ceci n'est pas grave pour l'utilisation de la séquence dans la base car les autres effets des transactions non valides ne seront pas visibles. Néanmoins, si vous souhaitez utiliser une valeur de séquence pour un stockage persistant hors de la base, assurez-vous que l'appel à nextval soit validé avant de l'utiliser hors base.