この記事はPostgreSQL9.4をベースに書いています。
create sequence
で start with 1
と指定すると、最初に nextval()
した時に 1
が返ってくる。
mydb=# create sequence hoge start with 1;
CREATE SEQUENCE
mydb=# select nextval('hoge');
nextval
---------
1
(1 row)
ここまでは良くて、次に値をリセットしたくて setval('hoge',1)
した後で nextval('hoge')
すると 2
が返ってきてファッ!?となった。
mydb=# select setval('hoge',1);
setval
--------
1
(1 row)
mydb=# select nextval('hoge');
nextval
---------
2
(1 row)
それならばと、0
をセットしてみるが、範囲外と怒られてしまう。
mydb=# select setval('hoge',0);
ERROR: setval: value 0 is out of bounds for sequence "hoge" (1..9223372036854775807)
それぞれの状態を調べてみると、create sequenceした直後は is_called
の値が false
だが、 setval
した直後は true
なようだ。
mydb=# select * from hoge;
sequence_name | last_value | start_value | increment_by | max_value | min_value | cache_value | log_cnt | is_cycled | is_called
---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
hoge | 1 | 1 | 1 | 9223372036854775807 | 1 | 1 | 0 | f | f
(1 row)
mydb=# select * from hoge;
sequence_name | last_value | start_value | increment_by | max_value | min_value | cache_value | log_cnt | is_cycled | is_called
---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
hoge | 1 | 1 | 1 | 9223372036854775807 | 1 | 1 | 0 | f | t
(1 row)
create sequence
は、nextval()
したタイミングで is_called
が true
になるようだ。
mydb=# create sequence hoge start with 1;
CREATE SEQUENCE
mydb=# select nextval('hoge');
nextval
---------
1
mydb=# select * from hoge;
sequence_name | last_value | start_value | increment_by | max_value | min_value | cache_value | log_cnt | is_cycled | is_called
---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
hoge | 1 | 1 | 1 | 9223372036854775807 | 1 | 1 | 32 | f | t
(1 row)
mydb=# select nextval('hoge');
nextval
---------
2
(1 row)
調べたら、setval
には第3引数に is_called
が指定できるようだ。デフォルトが true
なのは select setval('hoge', select MAX(id) from huga);
とかする時はその方が良いからかな。
mydb=# select setval('hoge',1,false);
setval
--------
1
(1 row)
mydb=# select nextval('hoge');
nextval
---------
1
(1 row)
alter sequence restart with
しても is_called
には false
が設定されるようだ。忘れた頃に setval
してハマる気がするので今後はこっち使うようにした方が良いかな。
mydb=# alter sequence hoge restart with 1;
ALTER SEQUENCE
mydb=# select * from hoge;
sequence_name | last_value | start_value | increment_by | max_value | min_value | cache_value | log_cnt | is_cycled | is_called
---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
hoge | 1 | 1 | 1 | 9223372036854775807 | 1 | 1 | 0 | f | f
(1 row)
mydb=# select nextval('hoge');
nextval
---------
1
(1 row)