助け合いフォーラム
この問題はプレミアムコンテンツです。
シーケンス操作関数について
【質問】
同一セッション内で該当のシーケンスに対してnextvalが一度も呼ばれていなければ、currval関数はエラーを返すと認識しています。
その為、回答としては④も正しいですが、②も正しいと思います。
しかし、【解説】ではcurrval関数は、この問題の条件ではエラーにはならず、「100を返す」と説明しています。
勉強中の身で解説の正しいor間違いを判断できないのと、調べても出てこないのでここで質問させて頂きます。
どうぞよろしくお願いいたします。
___________________________________________________
【問題文】
以下のSQLが実行された場合の説明として、正しいものはどれか。
CREATE SEQUENCE sample_seq CACHE 5 NO CYCLE;
SELECT setval('sample_seq', 100);
【選択肢】
①「SELECT nextval('sample_seq');」を実行すると105が返される
②「SELECT currval('sample_seq');」を実行するとエラーとなる
③「SELECT currval('sample_seq');」を実行すると5が返される
④「SELECT nextval('sample_seq');」を実行すると101が返される (正解はコレ)
⑤「SELECT nextval('sample_seq');」を実行すると100が返される
【解説】
1行ずつ確認していきます。
CREATE SEQUENCE sample_seq CACHE 5 NO CYCLE;
「sample_seq」シーケンスを作成しています。
オプションにより、メモリに格納できるシーケンス番号の量が5、シーケンスが限界値に達した時はエラーになるように設定されています。増減値は指定がないため、1ずつ増加します。
SELECT setval('sample_seq', 100);
シーケンスの現在の値を100に設定しています。
この場合、「SELECT currval('sample_seq');」を実行すると100が、「SELECT nextval('sample_seq');」を実行すると101が取得されます。
したがって正解は
・「SELECT nextval('sample_seq');」を実行すると101が返される
です。
_______________________________________________
少なくとも解説の実行例の通りにはなるようですね。
$ docker run --rm --name postgres -e POSTGRES_PASSWORD=postgres -d postgres
720321aa6c7d2cefb46d37adecc3938d34ea2daaff4958b49b309a8186f1edf3
$ docker exec -it postgres psql -U postgres
psql (17.2 (Debian 17.2-1.pgdg120+1))
Type "help" for help.
postgres=# CREATE SEQUENCE sample_seq CACHE 5 NO CYCLE;
CREATE SEQUENCE
postgres=# SELECT setval('sample_seq', 100);
setval
--------
100
(1 row)
postgres=# SELECT currval('sample_seq');
currval
---------
100
(1 row)
postgres=#
この状態で setval() で再度シーケンスの「現在値」を変更したら同じように設定後の「現在値」を返してくれます。
postgres=# SELECT setval('sample_seq', 200);
setval
--------
200
(1 row)
postgres=# SELECT currval('sample_seq');
currval
---------
200
(1 row)
nextval() を呼ぶかどうかが問題なのではなく「シーケンスを作成後に現在値が未設定の場合」に currval() を呼ぶと「現在値がないのでエラーになる」ということです。現在値を設定するには、「nextval() により初期値を取得する」か「setval() により任意の現在値を設定する」かのいずれかだということですね。
■ nextval() で初期化
postgres=# CREATE SEQUENCE sample_seq2 CACHE 5 NO CYCLE;
CREATE SEQUENCE
postgres=# SELECT currval('sample_seq2');
ERROR: currval of sequence "sample_seq2" is not yet defined in this session
postgres=# SELECT nextval('sample_seq2');
nextval
---------
1
(1 row)
postgres=# SELECT currval('sample_seq2');
currval
---------
1
(1 row)
■ setval() で任意の値を設定
postgres=# CREATE SEQUENCE sample_seq3 CACHE 5 NO CYCLE;
CREATE SEQUENCE
postgres=# SELECT currval('sample_seq3');
ERROR: currval of sequence "sample_seq3" is not yet defined in this session
postgres=# SELECT setval('sample_seq3', 35306);
setval
--------
35306
(1 row)
postgres=# SELECT currval('sample_seq3');
currval
---------
35306
(1 row)
コメント
この投稿に対して返信しませんか?
m mku2bull
2025/01/07 10:42
納得して理解できました!ご回答ありがとうございます!