INSERTした時にインクリメントされる、serial not null primary keyで指定したカラム値は、SELECT LASTVAL();で取得できます。
以下、実際にテーブルを作成し、INSERTした時の実行例を記します。
PostgreSQLのバージョンと作成したテーブルを以下に記します。
sakuradb=> select version();
version
-------------------------------------------------------------------------------------------------------
PostgreSQL 9.4.9 on armv7l-unknown-linux-gnueabihf, compiled by gcc (Raspbian 4.9.2-10) 4.9.2, 32-bit
(1 row)
CREATE TABLE tbl (id serial not null primary key, txt text);
2つのクライアントから作成したtblテーブルを操作します。
1つのPostgreSQLサーバに2つのクライアント(psqlフロントエンドを使用)を接続し、INSERTを発行してみます。
上記のテスト環境にする記した通り、AとBの2つのクライアントがPostgreSQLに接続しています。
以下に時系列で記します。
| A | B | |
| 1 | PostgreSQLに接続 | PostgreSQLに接続 |
| 2 | sakuradb=> INSERT INTO tbl(txt) VALUES('A-01') INSERT 0 1 sakuradb=> SELECT LASTVAL(); lastval --------- 1 (1 row) | |
| 3 | sakuradb=> INSERT INTO tbl(txt) VALUES('B-01'); INSERT 0 1 sakuradb=> SELECT LASTVAL(); lastval --------- 2 (1 row) | |
| 4 | sakuradb=> SELECT LASTVAL(); lastval --------- 1 (1 row) | |
| 5 | sakuradb=> INSERT INTO tbl(txt) VALUES('A-02'); INSERT 0 1 sakuradb=> SELECT LASTVAL(); lastval --------- 3 (1 row) |
上記を見るとわかるように、各クライアント側でINSERTした最後の値が LASTVAL() 関数で返却されているのが確認できます。
以下にBEGIN COMMIT ROLLBACKを使用した実行例を記します。
テーブルはDROP,CREATEしなおしました。
| A | B | |
| 1 | sakuradb=> BEGIN; BEGIN | |
| 3 | sakuradb=> INSERT INTO tbl(txt) VALUES('A-01'); INSERT 0 1 sakuradb=> SELECT LASTVAL(); lastval --------- 1 (1 row) | |
| 4 | sakuradb=> INSERT INTO tbl(txt) VALUES('B-01'); INSERT 0 1 sakuradb=> SELECT LASTVAL(); lastval --------- 2 (1 row) | |
| 5 | sakuradb=> ROLLBACK; ROLLBACK; | |
| 6 | sakuradb=> SELECT LASTVAL(); lastval --------- 1 (1 row) | |
| 7 | sakuradb=> INSERT INTO tbl(txt) VALUES('A-02'); INSERT 0 1 sakuradb=> SELECT LASTVAL(); lastval --------- 3 (1 row) |
上記の結果を見ると ROLLBACKしたINSERTは破棄され、LASTVALも登録されずインクリメントされているのが確認できます。
上記手順後にSELECT * した時の出力です。
id=1が登録されていないのが確認できます。
sakuradb=> SELECT * FROM tbl; id | txt ----+------ 2 | B-01 3 | A-02
以上、serial用に採番された値を取得するLASTVAL()の動作についてでした。