イメージとしてはこんな感じ。
create or replace function first_date_string_on_month(integer) returns varchar as $BODY$select to_char(date_trunc('month', current_date + interval '$1 months'), 'YYYY/MM/DD')$BODY$ language 'sql';だがこれだとうまくいかなくて、引数に何を与えても 2012/03/01 が返ってくる。
'$1 months' が '1 months' とみなされている気がする。
で、次にやってみたのがこんな感じ。
create or replace function first_date_string_on_month(integer) returns varchar as $BODY$select to_char(date_trunc('month', current_date + interval ($1 || ' months')), 'YYYY/MM/DD')$BODY$ language 'sql';構文エラーで登録すらできない。
interval だとだめなのかなと思って、interval のいらない current_timestamp で挑戦してみる。
create or replace function first_date_string_on_month(integer) returns varchar as $BODY$select to_char(date_trunc('month', current_timestamp + ($1 || ' months')), 'YYYY/MM/DD')$BODY$ language 'sql';「ERROR: 演算子が存在しません: date + text」と言われる。
なるほど text だからキャストが必要なのかと言うことで varchar にキャストしてみる。
create or replace function first_date_string_on_month(integer) returns varchar as $BODY$select to_char(date_trunc('month', current_timestamp + cast($1 || ' months' as varchar)), 'YYYY/MM/DD')$BODY$ language 'sql';これまた演算子が存在しないと言われる。
そういや、そもそも interval ってなんなんだ
と思って調べてみるとどうやらデータ型らしい。
interval '1 months' みたいに書くから識別子とかかと思ってたらデータ型でキャストというか型変換を意味していたのか!
というわけでこうしてみた。
create or replace function first_date_string_on_month(integer) returns varchar as $BODY$select to_char(date_trunc('month', current_timestamp + cast($1 || ' months' as interval)), 'YYYY/MM/DD')$BODY$ language 'sql';登録できたよ。
select first_date_string_on_month(3) -- → 2012/05/01 select first_date_string_on_month(-2) -- → 2011/12/01 select first_date_string_on_month(0) -- → 2012/02/01ちゃんと動いてるよ。
ちなみに reltime というデータ型もあるみたい。
create or replace function first_date_string_on_month(integer) returns varchar as $BODY$select to_char(date_trunc('month', current_timestamp + cast($1 || ' months' as reltime)), 'YYYY/MM/DD')$BODY$ language 'sql';とすると登録できて同じ結果が取得できた。
reltime型 を引数に取る interval 関数というのがあるので、それが関係していると思われるがよくわからない。
Google 先生で調べても PostgreSQL と realtime の検索結果が表示されるし。
とりあえず interval を使うのが正当だと思うのでそれでいいや。