私の目的は、テーブルに新しい行を挿入するときに主キーフィールドを自動的に挿入することです。
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
これはあなたが思っているより簡単かもしれません...
私の目的は、テーブルに新しい行を挿入するときに主キーフィールドを自動的に挿入することです。
列のデフォルト値を設定するだけです:
ALTER TABLE tbl ALTER COLUMN tbl_id SET DEFAULT nextval('my_seq'::regclass);
またはもっと簡単に、 serial
で始まるテーブルを作成します。
CREATE TABLE tbl(
tbl_id serial PRIMARY KEY
,col1 txt
-- more columns
);
専用のシーケンスを作成し、tbl_idのデフォルトを自動的に設定します。
こちらです tbl_id
は、INSERT
で言及されていない場合、添付されたシーケンスから次の値を自動的に割り当てられます。 anyセッション、同時または非同時で動作します。
INSERT INTO tbl(col1) VALUES ('foo');
新しいtbl_id
戻って何かをする:
INSERT INTO tbl(col1) VALUES ('foo') RETURNING tbl_id;
currval
は、現在のセッション内のシーケンスに対して生成された最後の値を返します。したがって、別のセッションがシーケンスの新しい値を生成した場合でも、エラーを回避して、YOURセッションによって生成された最後の値を取得できます。
ただし、セッションで最後に生成された値を取得するには、上記を使用できます。
SELECT last_value FROM your_sequence_name;
値がコミットされていない(または中止された)トランザクションで他のセッションで使用され、この値を参照として使用すると、エラーが発生する可能性があることに注意してください。通常、人々はcurrval
またはsetval
の戻りさえ必要とします。
この問題に対する実際的な答えを提供します。データベースサーバーは、プログラムとpsqlターミナルで使用されます。そのため、複数のセッションがあります。現在、私は私のpsqlターミナルにいます:
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)
自分のセッションでのみ値を表示できるようです。これは、別のセッションの実行にも影響します。これはおそらく、異なるセッションを分離するためのサーバーのマルチスレッド化に関連しています。カウンター(psqlのシリアル)は共有オブジェクトです。私の意見では、このセッションは、カウンターが適切にロックされ、単一のスレッド(セッション)のみがそれをインクリメントできる(アトミック操作)限り、カウンターの現在の値を取得できるはずです。しかし、ここで間違っている可能性があります(データベースサーバーライターの専門家ではありません)。
実際にはnextvalはシーケンスを進めて新しい値を返すので、それがあなたの質問に対する答えになります。
currvalは、指定されたシーケンスのnextvalで最後に取得された値を返します(ただし、現在のセッションでnextvalが使用されていない場合は失敗する可能性があります)。
この問題は断続的に発生しているようです。一貫性を保つために、CTEを使用して現在のセッションの挿入シーケンスを取得してください
WITH挿入AS(INSERT INTO notifn_main(notifn_dt、stat_id)SELECT now()、22 FROM notifn RETURNING id)挿入INTO tmp_idからIDを選択します。