#既存のInteger型の列をSerial型へ変更する
一般的な型変更の要領でalter table文を用いてSerial型へ変更しようとするとできない。
以下のようにERRORが出て怒られる。
alter table [table_name] alter column [colname] type serial;
ERROR: type "serial" does not exist
そこで、シーケンスオブジェクトを設定することで連番が取れるようにする。
※シーケンスオブジェクトとは?
シーケンスオブジェクトは通常テーブルの行に一意の識別子を生成するために使用されるもの
シーケンスは自動的に連番を生成するための仕組み
参考: https://www.postgresql.jp/document/7.4/html/functions-sequence.html
##①シーケンスオブジェクトを作成する
create sequence [table_name]_[colname]_seq;
シーケンス名については[テーブル名] _[対象カラム名]_seqとする例が多くみられる。
スタートを1からではなく数値[num]を設定したい場合は下記のようになる。
create sequence [table_name]_[colname]_seq start [num];
##②連番とするカラムのデフォルト値をシーケンス値とする
alter table [table_name] alter [colname] set default nextval('[table_name]_[colname]_seq');
連番として設定するカラムについて、デフォルト値をシーケンスの次の値とすることで連番を実現している。
nextval('hoge')関数は、行が挿入された時に、前回設定されたシーケンス値の次の値を列に設定する。
これでデータ挿入時の値の設定ができた。デフォルトでは1+increment_by (デフォルト 1)
##③テーブルと連動するように変更する
alter sequence [sequence_name] owned by [table_name].[colname];
owned byを付加することで、シーケンスを設定した列が削除したときに、そのシーケンス自体も削除されることとなる。
##④現在のsequence値を設定する
select setval('[sequence_name]', 1, false);
最後に、値を設定する。
ここで、第3引数にfalseを設定しておくのを忘れないようにする。
データが無い状態であれば1からの連番となる。
※select * from [sequence_name];でシーケンスの内容を確認すると、is_calledの値がTrueに設定されている。
この場合、現在last_valueである1の値が既に使用されていることとなる。
つまり、この状態から新しい値を追加すると2から始まることになる。
is_calledをfalseに設定しておくと、last_valueである1はまだ呼び出されていないため、新たな値を追加しても1から開始できる。
sequence_name | last_value | start_value | increment_by | max_value | min_value | cache_value | log_cnt | is_cycled | is_called
------------------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
stat_conditions_id_seq | 1 | 1 | 1 | 9223372036854775807 | 1 | 1 | 0 | f | t