3

次のテーブルがあるとします。

postgres=# create table foo (datetimes timestamptz);
CREATE TABLE
postgres=# \d+ foo 
                            Table "public.foo"
  Column   |           Type           | Modifiers | Storage | Description 
-----------+--------------------------+-----------+---------+-------------
 datetimes | timestamp with time zone |           | plain   | 
Has OIDs: no

それで、それにいくつかの値を挿入しましょう...

postgres=# insert into foo values 
    ('2012-12-12'), --This is the value I want to catch for.
    (null), 
    ('2012-12-12 12:12:12'), 
    ('2012-12-12 12:12');
INSERT 0 4

そして、ここに私たちが持っているものがあります:

postgres=# select * from foo ;
       datetimes        
------------------------
 2012-12-12 00:00:00+00

 2012-12-12 12:12:12+00
 2012-12-12 12:12:00+00
(4 rows)

2012-12-12理想的には、入力に TIME が指定されていない場合のデフォルトのタイムスタンプ値を設定したいと思います。デフォルト00:00:00の を設定したいと思います15:45:10

つまり、私の結果次のようになります。

postgres=# select * from foo ;
       datetimes        
------------------------
 2012-12-12 15:45:10+00    --This one gets the default time.

 2012-12-12 12:12:12+00
 2012-12-12 12:12:00+00
(4 rows)

postgres 8.4でこれを行う方法がよくわかりません。マニュアルの日時セクションまたは列のデフォルト値に関するセクションには何も見つかりません。

4

1 に答える 1

3

BEFORE INSERT新しい行の値は、トリガーで微調整できます。このようなトリガーは、 にゼロ以外の時間コンポーネントがあるかどうかをテストしNEW.datetimes、そうでない場合は目的の固定時間に設定できます。

ただし、 INSERT 句で時間部分が明示的にゼロに設定されている場合は、'2012-12-12'::timestamptzが と等しいため、この手法では処理できません'2012-12-12 00:00:00'::timestamptz。つまり、0.0 と 0.00 を区別しようとしているのと同じです。

技術的には、文字列から列の型への暗黙的なキャストの前に値を微調整する必要がありますが、これはRULE(動的クエリの書き換え) でも実行できません。

INSERT を書き直して、文字列からタイムスタンプに明示的に変換する各値に関数を適用するのが最善の方法だと私には思えます。この関数は、入力形式をテストし、必要に応じて時間部分を追加します。

  create function conv(text) returns timestamptz as $$
    select case when length($1)=10 then ($1||' 15:45:10')::timestamptz
      else $1::timestamptz end; $$
   language sql strict immutable;

insert into foo values 
    (conv('2012-12-12')),
    (conv(null)), 
    (conv('2012-12-12 12:12:12')), 
    (conv('2012-12-12 12:12'));
于 2012-06-13T10:36:41.250 に答える