J'ai une table:
CREATE TABLE names (id serial, name varchar(20))
Je veux le "dernier identifiant inséré" de cette table, sans utiliser RETURNING id
on insert. Il semble y avoir une fonction CURRVAL()
, mais je ne comprends pas comment l’utiliser.
J'ai essayé avec:
SELECT CURRVAL() AS id FROM names_id_seq
SELECT CURRVAL('names_id_seq')
SELECT CURRVAL('names_id_seq'::regclass)
mais aucun d'entre eux ne fonctionne. Comment puis-je utiliser currval()
pour obtenir le dernier identifiant inséré?
postgresql
sequence
Jonas
la source
la source
currval()
n'est certainement pas découragée.Réponses:
Si vous créez une colonne en tant que
serial
PostgreSQL ™ crée automatiquement une séquence pour cela.Le nom de la séquence est généré automatiquement et est toujours nom_table_nom_colonne_seq. Dans votre cas, la séquence sera nommée
names_id_seq
.Après avoir inséré dans la table, vous pouvez appeler
currval()
avec ce nom de séquence:Au lieu de coder en dur le nom de la séquence, vous pouvez également utiliser
pg_get_serial_sequence()
:De cette façon, vous n’avez pas besoin de vous fier à la stratégie de nommage utilisée par Postgres.
Ou si vous ne souhaitez pas utiliser le nom de la séquence, utilisez
lastval()
la source
currval()
dans une configuration multi-utilisateur. Par exemple, sur un serveur Web.currval()
est "local" à votre connexion actuelle. Il n'y a donc aucun problème à l'utiliser dans un environnement multi-utilisateur. C'est tout le but d'une séquence.Ceci vient directement de Stack Overflow
Comme l'ont souligné @a_horse_with_no_name et @Jack Douglas, currval ne fonctionne qu'avec la session en cours. Donc, si vous êtes d'accord avec le fait que le résultat peut être affecté par une transaction non validée d'une autre session et que vous souhaitez toujours quelque chose qui fonctionnera sur plusieurs sessions, vous pouvez utiliser ceci:
Utilisez le lien vers SO pour plus d'informations.
D'après la documentation de Postgres , il est clairement indiqué que
Donc, je suppose que, à proprement parler, pour utiliser correctement currval ou last_value pour une séquence sur plusieurs sessions, vous auriez besoin de faire quelque chose comme ça?
En supposant, bien sûr, que vous n'ayez pas d'insertion ou de toute autre manière d'utiliser le champ série dans la session en cours.
la source
nextval()
vous devez ensuite définir manuellement la séquence pour qu'elle corresponde au nombre d'enregistrements de fixture que vous avez insérés avec les ID codés en dur. De plus, le moyen de résoudre le problème de currval () / lastval () n'étant pas disponible pré-nextval est uniquementSELECT
sur la séquence directement.Vous devez appeler
nextval
pour cette séquence dans cette session avantcurrval
:vous ne pouvez donc pas trouver le "dernier identifiant inséré" dans la séquence à moins que l'opération
insert
soit effectuée dans la même session (une transaction peut être annulée mais la séquence ne le sera pas)comme indiqué dans la réponse de a_horse,
create table
une colonne de typeserial
créera automatiquement une séquence et l'utilisera pour générer la valeur par défaut de la colonne, de sorte qu'un utilisateurinsert
accède normalement denextval
manière implicite:la source
Donc, il y a quelques problèmes avec ces différentes méthodes:
Currval n'obtient que la dernière valeur générée dans la session en cours - ce qui est très bien si vous n'avez rien d'autre qui génère des valeurs, mais dans les cas où vous pouvez appeler un déclencheur et / ou faire avancer la séquence plus d'une fois dans la transaction en cours, c'est ne va pas retourner la valeur correcte. Ce n'est pas un problème pour 99% des gens là-bas - mais c'est quelque chose que l'on devrait prendre en considération.
Le meilleur moyen d'obtenir l'identificateur unique attribué après une opération d'insertion consiste à utiliser la clause RETURNING. L'exemple ci-dessous suppose que la colonne liée à la séquence s'appelle "id":
Notez que l’utilité de la clause RETURNING va bien au-delà de l’obtention de la séquence, car elle aura également:
Renvoie les valeurs en cours de suppression:
supprimer de la table A où id> 100 retournant *
Renvoie les lignes modifiées après un UPDATE:
mettre à jour la table A set X = 'y' où blah = 'blech' retournant *
Utilisez le résultat d'une suppression pour une mise à jour:
WITH A en tant que (supprimer * de la table A en tant qu'identifiant renvoyé) update B set delete = true où id in (sélectionnez id de A);
la source
RETURNING
clause - mais rien de mal à rendre les avantages de l'utiliser plus clair pour les autres.J'ai dû exécuter une requête malgré l'utilisation de SQLALchemy car je n'avais pas réussi à utiliser currval.
Il s’agissait d’un projet flacon en python + postgresql.
la source
Si vous voulez obtenir la valeur des séquences sans avoir appelé
nextval()
et sans avoir à modifier la séquence, j'ai assemblé une fonction PL / pgSQL pour la gérer: Trouvez la valeur de toutes les séquences de la base de donnéesla source
Vous devez
GRANT
utiliser le schéma, comme ceci:et
la source
currval()
fonction pour la rendre un peu plus pertinente pour ce fil?Dans PostgreSQL 11.2, vous pouvez traiter la séquence comme une table, il semble:
Exemple si vous avez une séquence nommée: 'names_id_seq'
Cela devrait vous donner le dernier identifiant inséré (4 dans ce cas), ce qui signifie que la valeur actuelle (ou la valeur à utiliser pour l'identifiant suivant) devrait être 5.
la source
Différentes versions de PostgreSQL peuvent avoir différentes fonctions pour obtenir l'identifiant de séquence actuel ou suivant.
Tout d’abord, vous devez connaître la version de votre Postgres. Utilisation de select version (); pour obtenir la version.
Dans PostgreSQL 8.2.15, vous obtenez l'ID de la séquence actuelle en utilisant
select last_value from schemaName.sequence_name
.Si la déclaration ci-dessus ne fonctionne pas, vous pouvez utiliser
select currval('schemaName.sequence_name');
la source