假设我有桌子:
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
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中执行此操作,我在手册的datetime部分或有关列默认值的部分中找不到任何内容。
答案 0 :(得分: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'));