Обсуждение: Defaulting a column to 'now'
<div class="Section1"><p class="MsoNormal"><font face="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana">How can a column’s default be set to ‘now’, meaning ‘now’ as of when each row is inserted?</span></font><pclass="MsoNormal"><font face="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana"> </span></font><p class="MsoNormal"><font face="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana">For example, here’s a snip of DDL:</span></font><p class="MsoNormal"><font face="Verdana" size="2"><spanstyle="font-size:10.0pt; font-family:Verdana"> </span></font><p class="MsoNormal"><font face="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana">create table personal_data (…</span></font><p class="MsoNormal"><font face="Verdana" size="2"><spanstyle="font-size:10.0pt; font-family:Verdana">effective_date_and_time TIMESTAMP WITH TIME ZONE not null default 'now',…</span></font><p class="MsoNormal"><fontface="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana"> </span></font><p class="MsoNormal"><font face="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana">The problem is, when PostgreSQL processes this DDL, it interprets the ‘now’ as the timestamp when thetable is created, so that the tables definition reads as if the DDL were:</span></font><p class="MsoNormal"><font face="Verdana"size="2"><span style="font-size:10.0pt; font-family:Verdana"> </span></font><p class="MsoNormal"><font face="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana">effective_date_and_time TIMESTAMP WITH TIME ZONE not null default '</span></font> <font face="Verdana"size="2"><span style="font-size:10.0pt; font-family:Verdana">2005-12-14 11:00:16.749616-06 ',</span></font><p class="MsoNormal"><font face="Verdana" size="2"><spanstyle="font-size:10.0pt; font-family:Verdana"> </span></font><p class="MsoNormal"><font face="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana">so all of the newly inserted rows get assigned effective_date_and_time = '</span></font> <font face="Verdana"size="2"><span style="font-size:10.0pt; font-family:Verdana">2005-12-14 11:00:16.749616-06 ', which in addition to being wrong leads to uniqueness constraint violations.</span></font><pclass="MsoNormal"><font face="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana"> </span></font><p class="MsoNormal"><font face="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana">~ TIA</span></font><p class="MsoNormal"><font face="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana">~ Ken</span></font><p class="MsoNormal"><font face="Verdana" size="2"><span style="font-size:10.0pt; font-family:Verdana"> </span></font></div>
"Ken Winter" <ken@sunward.org> writes:
> How can a column's default be set to 'now', meaning 'now' as of when each
> row is inserted?
You need a function, not a literal constant. The SQL-spec way isCURRENT_TIMESTAMP
(which is a function, despite the spec's weird idea that it should be
spelled without parentheses); the traditional Postgres way isnow()
Either way only sets an insertion default, though. If you want to
enforce a correct value on insertion, or change the value when the
row is UPDATEd, you need to use a trigger.
regards, tom lane
Ken Winter wrote: > How can a column’s default be set to ‘now’, meaning ‘now’ as of when > each row is inserted? > > > > For example, here’s a snip of DDL: > > > > create table personal_data (… > > effective_date_and_time TIMESTAMP WITH TIME ZONE not null default 'now',… > try with now(), instead of now ... effective_date_and_time TIMESTAMPTZ not null default now()...
On Wed, 14 Dec 2005 13:10:50 -0500, Ken Winter wrote
> How can a column's default be set to 'now', meaning 'now' as of when each
> row is inserted?
>
> For example, here's a snip of DDL:
>
> create table personal_data (.
>
> effective_date_and_time TIMESTAMP WITH TIME ZONE not null default
> 'now',.
>
> The problem is, when PostgreSQL processes this DDL, it interprets the 'now'
> as the timestamp when the table is created, so that the tables definition
> reads as if the DDL were:
>
> effective_date_and_time TIMESTAMP WITH TIME ZONE not null default '
> 2005-12-14 11:00:16.749616-06 ',
>
> so all of the newly inserted rows get assigned effective_date_and_time
> = '
> 2005-12-14 11:00:16.749616-06 ', which in addition to being wrong
> leads to uniqueness constraint violations.
>
> ~ TIA
>
> ~ Ken
Ken,
effective_date_and_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT
('now'::text)::timestamp(6) with time zone
Kind Regards,
Keith
Thanks, Tom (also Keith Worthington and Bricklen Anderson). That works. ~ Ken > -----Original Message----- > From: Tom Lane [mailto:tgl@sss.pgh.pa.us] > Sent: Wednesday, December 14, 2005 1:15 PM > To: Ken Winter > Cc: PostgreSQL pg-sql list > Subject: Re: [SQL] Defaulting a column to 'now' > > "Ken Winter" <ken@sunward.org> writes: > > How can a column's default be set to 'now', meaning 'now' as of when > each > > row is inserted? > > You need a function, not a literal constant. The SQL-spec way is > CURRENT_TIMESTAMP > (which is a function, despite the spec's weird idea that it should be > spelled without parentheses); the traditional Postgres way is > now() > > Either way only sets an insertion default, though. If you want to > enforce a correct value on insertion, or change the value when the > row is UPDATEd, you need to use a trigger. > > regards, tom lane