currval non è ancora stata definita questa sessione, come arrivare multi-sessione di sequenze?

Il mio obiettivo è quello di ottenere un campo chiave primaria viene inserito automaticamente quando si inserisce una nuova riga nella tabella.

Come ottenere una sequenza che va da sessione a sessione in 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
  • Lo scopo di una sequenza di sessione locale. Non si riesce a “mano” il currval oltre a un’altra sessione. Perché pensi di averne bisogno? Perché non fare tutto in una singola transazione?
  • perché ho due sessioni aperte contemporaneamente : un amministratore di uno e una di produzione. Quindi devo avere due sessioni separate.
  • perché non creare una singola sequenza e poi basta la condivisione tra le due sessioni? Essi ‘ re ottenere un id univoco lavoro fatto.

 

5 Replies
  1. 15

    Questo può essere più semplice di quanto si pensi …

    Il mio obiettivo è quello di ottenere un campo chiave primaria inseriti automaticamente quando
    inserimento nuova riga nella tabella.

    Basta impostare il valore predefinito della colonna:

    ALTER TABLE tbl ALTER COLUMN tbl_id SET DEFAULT nextval('my_seq'::regclass);

    O più semplice, creare la tabella con un serie tipo di chiave primaria per iniziare:

    CREATE TABLE tbl(
      tbl_id serial PRIMARY KEY
     ,col1 txt
      -- more columns
    );

    Crea un dedicato sequenza e imposta il valore predefinito per tbl_id automaticamente.

    Questo modo tbl_id viene assegnato il valore successivo allegato sequenza automaticamente se non menzione nel INSERT. Funziona con qualsiasi sessione, simultanee o non.

    INSERT INTO tbl(col1) VALUES ('foo');

    Se si desidera che il nuovo tbl_id torna a fare qualcosa con esso:

    INSERT INTO tbl(col1) VALUES ('foo') RETURNING tbl_id;
  2. 85

    Il currval restituirà l’ultimo valore generato per la sequenza all’interno della sessione corrente. Quindi, se un’altra sessione genera un nuovo valore per la sequenza è ancora possibile recuperare l’ultimo valore generato dalla VOSTRA sessione, evitando errori.

    Ma, per ottenere l’ultimo valore generato in tutte le sessioni, è possibile utilizzare il precedente:

    SELECT last_value FROM your_sequence_name;

    Attenzione, se il valore è stato utilizzato da altri sessione con un uncommited (o annullata) transazione e si utilizza questo valore come riferimento, si può ottenere un errore. In genere la gente solo bisogno di currval o anche il ritorno di setval.

    • Come ottenere l’ultimo valore generato dall’altra sessione. Se sto usando un cantante DB Utente sarà ancora l’effetto precisione?
    • Actionally è interessante, perché la possibilità di SELECT * FROM sequence non è citato anche nella documentazione ufficiale ?
  3. 7

    Mi darà una risposta concreta per questa materia.
    Il mio server di database è utilizzato da i miei programmi e i miei psql terminale; quindi non ci sono più sessioni. attualmente mi trovo nel mio psql terminale:

    fooserver=> select currval('fusion_id_seq');
    ERROR:  currval of sequence "fusion_id_seq" is not yet defined in this session
    fooserver=> select nextval('fusion_id_seq');
     nextval 
    ---------
      320032
    (1 row)
    
    fooserver=> select currval('fusion_id_seq');
     currval 
    ---------
      320032
    (1 row)

    Sembra che si può vedere solo i valori nella propria sessione. Questo influenzerà anche il currval di un’altra sessione. Questo è probabilmente legato al multi-threading del server per isolare le diverse sessioni. Il contatore (di serie in psql) è un oggetto condiviso. A mio parere, questa sessione dovrebbe essere in grado di ottenere il valore corrente del contatore finché il contatore è bloccato correttamente per garantire un solo thread (sessione) può incrementarlo (operazione atomica). Ma potrei sbagliarmi, qui (non sono un esperto di database server scrittore).

  4. 2

    Effettivamente nextval vi anticipo sequenza e restituisce il nuovo valore, in modo che sarebbe la risposta per la tua domanda.

    currval restituirà il valore più recentemente ottenuto con nextval for sequenza specificata (Questo però potrebbe non riuscire se non ci fosse nextval utilizzato nella sessione corrente).

  5. 1

    Questo problema sembra essere intermittente , Per consistenza uso CTE per ottenere la sequenza inserita per la sessione corrente

    CON inserito (
    INSERT INTO notifn_main (notifn_dt,stat_id)
    SELEZIONARE ora(),22
    DA notifn
    TORNANDO id )
    SELEZIONARE l’id
    inserite IN tmp_id;

Lascia un commento