2 votes

Les valeurs des colonnes PostgreSQL doivent être dans une séquence

Comment puis-je définir une colonne dans PostgreSQL de telle sorte que chaque valeur doit être dans une séquence, et non pas la séquence que vous obtenez en utilisant le type serial mais une telle qu'une valeur 2 ne peut être insérée que si une valeur 1 existe déjà dans la colonne ?

1voto

Craig Ringer Points 72371

J'ai écrit un exemple détaillé de la mise en œuvre d'une séquence sans faille en utilisant PL/PgSQL. aquí .

L'idée générale est que vous voulez une table pour stocker les valeurs de la séquence, et vous utilisez SELECT ... FOR UPDATE suivi par UPDATE - ou le raccourci UPDATE ... RETURNING - pour en extraire des valeurs tout en verrouillant la ligne jusqu'à ce que votre transaction soit validée ou annulée.

0voto

En théorie, vous pourriez utiliser une contrainte qui fonctionnerait comme suit. (Mais cela ne fonctionnera pas en pratique).

  1. Comptez les rangs.
  2. Évaluer max(column) - min(column) + 1 .
  3. Comparez les résultats.

Vous devrez probablement insérer une ligne avant de créer la contrainte CHECK. Si vous ne le faites pas, max(column) renvoie NULL. Avec une ligne,

  1. Comptez les rangs (1).
  2. Évaluer max(column) - min(column) + 1 . (1 - 1 + 1 = 1)
  3. Comparez les résultats. (1 = 1)

Avec 10 rangs .

  1. Comptez les rangs (10).
  2. Évaluer max(column) - min(column) + 1 . (10 - 1 + 1 = 10)
  3. Comparez les résultats. (10 = 10)

Le fait que la séquence commence à 1 n'a pas d'importance ; cette façon de vérifier montrera toujours un vide s'il existe. Si vous aviez besoin de garantir que la séquence sans vide commence à 1, vous pourriez l'ajouter à la contrainte CHECK.

Pour autant que je sache, il n'y a aucun moyen de faire cela de manière déclarative avec les bases de données actuelles. Pour le faire, vous auriez besoin du support de CREATE ASSERTION . (Mais je peux me tromper.) Dans PostgreSQL, je pense que votre seule chance d'y parvenir implique du code procédural dans plusieurs triggers AFTER.

Je n'ai qu'une seule table qui doit être sans espace. C'est une table de calendrier. Nous exécutons une requête une fois par nuit qui fait ces calculs, et elle me permet de savoir si j'ai un écart.

-1voto

C. Ramseyer Points 1141

Vous écrivez un on insert tigger ou un check constraint . Cependant, cela permettra toujours de supprimer "1" par la suite et "2" reste dans la table, vous devrez probablement vous occuper de cela aussi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X