PostgreSQL小ネタ(Oracleの関数 last_day)

PostgreSQL database

OracleからPostgreSQLに移行を決めたとき

私は元々Oracleを触っていたのですが、PostgreSQLに移行を検討したとき、同じRDBMSとはいえ「方言の違い」に悩まされました。例えば現在時刻を取得するにしても

Oracle
SELECT SYSDATE FROM DUAL;

に対し

PostgreSQL
SELECT now();

このように使用する関数が異なる場合があるからです(それよりFROM句が無くても良いことが衝撃でした)。

last_dayが無いなら作ってしまおう

しかし、これはSYSDATEをnow()に変えれば実現できますが「そもそもそんなものは無い」という関数も存在しました。その中で私が良く使っていたものの一つに「last_day」があります。いわずと知れた「その月の最終日を取得する」ための関数です。

PostgreSQLにも日付を操作する関数は勿論ありますが、こんなときはファンクションを自前で作成してしまえば良いと思います。DB丸ごと移行するとなれば、僅かな違いでも要修正箇所が膨大な量になるからです。

余談ですがPostgreSQLでOracleのストアドプロシージャにあたるものはファンクションになり、必ず戻り値を付けねばなりません(戻り値不要のファンクションではreturns voidとなります)。

ファンクション作成

create or replace function last_day(in date) returns date as $$
	select (((to_char(($1 + interval '1month'), 'yyyy-mm')) || '-01')::date - interval '1day')::date;
$$ language sql;

やっていることは簡単です。月末を求めたい日付を引数で渡し、1か月加算してyyyy-mmの文字列にした後’-01’を付与。日付に戻して1日引いたものを返却します。2020年7月12日を引数で渡した場合はこんな感じです。

2020-07-12(引数)
2020-08-12(1か月足す)
2020-08   (yyyy-mmの文字列にする)
2020-08-01(-01を付与して日付に戻す)
2020-07-31(1日引いた値が戻り値)

実行してみます。

sandambara=# select last_day('2020-07-12');
  last_day
------------
 2020-07-31
(1 行)

ストアドやファンクションはドカッとまとまった処理をやらせるだけでなく、こんな風に「あったらいいな」を叶えてくれる便利な機能です。無い機能に落胆せず、あなたの色に染めていきましょう!

コメント