currval n'a pas encore été définie de cette session, comment faire du multi-session séquences?
Mon objectif est d'obtenir un champ de clé primaire inséré automatiquement lors de l'insertion d'une nouvelle ligne dans la table.
Comment faire pour obtenir une séquence allant de la session à l'autre dans PostgreSQL?
doubleemploi@hanbei:/home/yves$ psql -d test
Mot de passe :
psql (8.4.13)
Saisissez « help » pour l''aide.
test=> create sequence test001 start 10;
CREATE SEQUENCE
test=> select currval('test001');
ERREUR: la valeur courante (currval) de la séquence « test00 » n''est pas encore définie dans cette session
--- current value not yet defined this session (???)
test=> select setval('test001', 10);
setval
--------
10
(1 ligne)
test=> select currval('test00');
currval
---------
10
(1 ligne)
test=> \q
test@hanbei:/home/yves$ psql -d test
Mot de passe :
psql (8.4.13)
Saisissez « help » pour l''aide.
test=> select currval('test001');
ERREUR: la valeur courante (currval) de la séquence « test00 » n''est pas encore définie dans cette session
- Le but de la séquence est celle de l'session locale. Vous ne pouvez pas "la main" le currval au cours d'une autre session. Pourquoi croyez-vous besoin? Pourquoi ne pas tout faire en une seule opération?
- parce que j'ai deux session s'est ouverte en même temps : un administrateur de l'un et de production. Donc je dois avoir deux sessions distinctes.
- pourquoi ne pas créer une séquence unique, et puis il suffit de le partager entre les deux sessions? Ils sont obtenir des identifiants uniques, le travail est accompli.
Vous devez vous connecter pour publier un commentaire.
Cela peut être plus simple que vous le pensez ...
Il suffit de régler la valeur par défaut de la colonne:
Ou plus simple encore, créer la table avec un
série
type de clé primaire pour commencer:Il crée une séquence dédiée et définit la valeur par défaut pour tbl_id automatiquement.
De cette façon
tbl_id
est affecté à la valeur suivante de la séquence automatiquement si vous ne le mentionnez pas dans leINSERT
. Fonctionne avec tout session, simultanées ou non.Si vous souhaitez que la nouvelle
tbl_id
retour à faire quelque chose avec elle:La
currval
renvoie la dernière valeur générée pour la séquence dans la session en cours. Donc, si une autre session génère une nouvelle valeur pour la séquence, vous pouvez toujours récupérer la dernière valeur générée par VOTRE session, en évitant les erreurs.Mais, pour obtenir la dernière valeur générée sur toutes les sessions, vous pouvez utiliser le haut:
Attention, si la valeur a été utilisée par d'autres session avec un uncommited (ou abandonné) de transaction et d'utiliser cette valeur comme référence, vous pouvez obtenir une erreur. Généralement, les gens juste besoin de la
currval
ou même le retour desetval
.SELECT * FROM sequence
n'est même pas mentionné dans la documentation officielle ?Je vais donner une réponse pratique à cette question.
Mon serveur de base de données est utilisée par mes programmes et mes psql terminal; il y a donc plusieurs sessions. actuellement, je suis dans mon psql terminal:
Il semble que vous ne pouvez voir les valeurs dans votre propre session. Cela affectera également la currval d'une autre session. Ceci est probablement lié au multi-threading pour le serveur d'isoler les différents session. Le compteur (de série dans psql) est un objet partagé. À mon avis, cette session devrait être en mesure d'obtenir la valeur courante du compteur tant que le compteur est correctement verrouillé afin d'assurer un seul thread (session) peut incrémenter (opération atomique). Mais je peux me tromper ici (pas un expert sur le serveur de base de données de l'écrivain).
Fait nextval avance séquence et le retour de la nouvelle valeur, alors que ce serait la réponse à votre question.
currval sera de retour la valeur la plus récemment obtenus avec nextval pour l'ordre indiqué (Ce que peut échouer si il n'y avait pas nextval utilisés dans la session en cours).
Ce problème semble être intermittent , Pour des raisons de cohérence utilisation CTE pour obtenir la séquence insérée pour la session en cours
AVEC insérés en tant QUE (
INSÉREZ DANS notifn_main (notifn_dt,stat_id)
SELECT now(),22
DE notifn
Le RETOUR de l'id )
SELECT id
à partir inséré DANS tmp_id;