しゃのんあどべんとかれんだー 25 日目 (PostgreSQL の now() の罠(?)) 匿名 匿名 この記事は、しゃのんあどべんとかれんだー 25 日目の記事です。 ![PostgreSQL](http://3.bp.blogspot.com/-MRNGuhjwlOw/Vop1NgVwlOI/AAAAAAAAAXA/AmgAFlsA3dE/s200/postgresql.png) どうも、munepom (`@__munepom__`) です。 あ、気が付いたら年が明けていましたw とりあえず小ネタ系を書けるだけ書いてみようという試みのラストは、PostgreSQL の現在時刻取得に関する小ネタです。 いやー、入念に準備しないと、なかなかキツイということが分かりましたw # 現在時刻のタイムスタンプ値を取得したい場合 非標準SQLですが、now() って便利ですよね。 こんな風に、現在時刻のタイムスタンプを取得できます。 ``` postgres=# SELECT now(); now ------------------------------- 2016-01-01 01:31:22.772938+09 (1 row) ``` あ、今回は、全て Docker Hub の Postgresql 9.4.5 で試しました。 https://hub.docker.com/_/postgres/ CoreOS で `$ docker run -d --name postgresql9.4 postgres:9.4` を実行してコンテナを起動後、 `$ docker exec -it postgresql9.4 bash` を実行して、コンテナへ侵入しちゃいます。 あとは、コンテナで `# psql -U postgres` を実行すれば、psql コンソールを起動できます。 (CoreOS に psql が無いものでして。。。) # now() の罠 でも、`SELECT now();` で取得できるタイムスタンプは、トランザクション開始時刻です。 ドキュメントをちゃんと読まないと、地雷を踏む可能性がありますね。 https://www.postgresql.jp/document/9.4/html/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT (ドキュメントを読む限りでは、標準SQLだと現在のトランザクションの開始時刻に基づいた値を取得できない疑惑ですが。。。) # じゃあ、実際の現在時刻を知るには? どのような情報を登録/更新したいのかによりますが、clock_timestamp() や statement_timestamp() を使うと良さげでしょうか? statement_timestamp() では、現在の文の実行開始時刻を返すようです。(直前のコマンドメッセージをクライアントから受け取った時刻のようです) 試してみました。 ``` postgres=# BEGIN;SELECT now();SELECT pg_sleep(1);SELECT transaction_timestamp(), statement_timestamp(), clock_timestamp(), statement_timestamp(), clock_timestamp();COMMIT; BEGIN now ------------------------------- 2016-01-01 01:55:50.047496+09 (1 row) pg_sleep ---------- (1 row) transaction_timestamp | statement_timestamp | clock_timestamp | statement_timestamp | clock_timestamp -------------------------------+-------------------------------+-------------------------------+-------------------------------+------------------------------- 2016-01-01 01:55:50.047496+09 | 2016-01-01 01:55:51.052205+09 | 2016-01-01 01:55:51.052332+09 | 2016-01-01 01:55:51.052205+09 | 2016-01-01 01:55:51.052333+09 (1 row) COMMIT ``` 確認の結果、 now() と transaction_timestamp() はトランザクション開始時刻を、 statement_timestamp() は、現在の文の実行開始時刻を、 clock_timestamp() は、実際の現在時刻を返すことがわかりました。メソッドを実行した時間のようですね。 日々コツコツと、、、レッツ Enjoy! (・ω・)ノ Tweet Share Share Share Share