postgreSQL 将列数据类型更改为没有时区的时间戳

Posted

技术标签:

【中文标题】postgreSQL 将列数据类型更改为没有时区的时间戳【英文标题】:postgreSQL alter column data type to timestamp without time zone 【发布时间】:2017-08-20 21:50:59 【问题描述】:

我想将一列数据从文本更改为类型时间戳。我的数据中没有时区。我的数据格式是 28-03-17 17:22,包括时间和日期,但没有时区。换句话说,我所有的数据都在同一个时区。我该怎么做?

我尝试了以下多种方法,但仍然找不到正确的方法。希望你能帮助我。

当然,如果我的问题能解决,我可以建一个新表。

alter table AB
alter create_time type TIMESTAMP;

ERROR:  column "create_time" cannot be cast automatically to type timestamp without time zone
HINT:  You might need to specify "USING create_time::timestamp without time zone".
********** Error **********

ERROR: column "create_time" cannot be cast automatically to type timestamp without time zone
SQL state: 42804
Hint: You might need to specify "USING create_time::timestamp without time zone".
alter table AB
alter create_time type TIMESTAMP without time zone;

ERROR:  column "create_time" cannot be cast automatically to type timestamp without time zone
HINT:  You might need to specify "USING create_time::timestamp without time zone".
********** Error **********

ERROR: column "create_time" cannot be cast automatically to type timestamp without time zone
SQL state: 42804
Hint: You might need to specify "USING create_time::timestamp without time zone".
alter table AB
alter create_time::without time zone type TIMESTAMP;

ERROR:  syntax error at or near "::"
LINE 2:  alter create_time::without time zone type TIMESTAM
                          ^
********** Error **********

ERROR: syntax error at or near "::"
SQL state: 42601
Character: 50
alter table AB
alter create_time UTC type TIMESTAMP;

ERROR:  syntax error at or near "UTC"
LINE 2: alter create_time UTC type TIMESTAMP;
                          ^
********** Error **********

ERROR: syntax error at or near "UTC"
SQL state: 42601
Character: 50

【问题讨论】:

作为一般规则,请在您的问题中包含任何相关的错误消息。如果没有错误,请说明您认为它没有按预期工作的为什么。说它“不是正确的方法”不是很有帮助或细节。 添加了所有错误。请检查一下。谢谢。 阅读错误信息和您的代码:USING create_time::timestamp without time zone 与您的代码:create_time::without time zone type TIMESTAMP; 【参考方案1】:

USING... 位于类型之后:

... alter create_time type TIMESTAMP USING create_time::TIMESTAMP;

【讨论】:

错误:日期/时间字段值超出范围:“23/03/2017 05:20:02”提示:也许您需要不同的“日期样式”设置。 ********** 错误 ********** 错误:日期/时间字段值超出范围:“23/03/2017 05:20:02” SQL 状态:22008 提示:也许您需要不同的“日期样式”设置。 这是我的查询,它在 postgresql 10.5 上完美运行。 "alter table tmp_usersgroups alter column datecreated type timestamp using datecreated::timestamp;" @Amy , set datestyle to 'sql,dmy'【参考方案2】:

您没有指定 create_time 的原始类型,所以我假设它是带时区的 TIME(因为在尝试更改为不带时区的 TIMESTAMP 时,带时区的类型 DATE 或 TIMESTAMP 不应给出上述错误)。由于 TIMESTAMP 除了 TIME 之外还有日期信息,因此您需要在 ALTER 语句中补充日期信息,例如:

ALTER TABLE AB ALTER COLUMN create_time TYPE TIMESTAMP without time zone USING date('20170327') + create_time;

如果您有相应的 DATE 列(例如 create_date),您可以将其传递给 date() 函数,例如:

ALTER TABLE AB ALTER COLUMN create_time TYPE TIMESTAMP without time zone USING date(create_date) + create_time;

【讨论】:

感谢您的回答。我设置的数据类型是开头的文本,因为数据就像'28-03-17 17:22',包括时间和日期,但没有时区。 我已经发布了我的 cmets 作为另一个答案 - cmets 部分对于显示多行代码来说太有限了。【参考方案3】:

如果create_time 是具有有效日期值的 TEXT 类型,则进行如下更改会更容易(建议先进行表转储作为备份):

-- Create a temporary TIMESTAMP column
ALTER TABLE AB ADD COLUMN create_time_holder TIMESTAMP without time zone NULL;

-- Copy casted value over to the temporary column
UPDATE AB SET create_time_holder = create_time::TIMESTAMP;

-- Modify original column using the temporary column
ALTER TABLE AB ALTER COLUMN create_time TYPE TIMESTAMP without time zone USING create_time_holder;

-- Drop the temporary column (after examining altered column values)
ALTER TABLE AB DROP COLUMN create_time_holder;

【讨论】:

嗨,里奥。设置 "set datestyle = "ISO, DMY" 是正确的方法。非常感谢!! 更改格式后,我现有的所有数据都很好。但问题是,当我尝试导入以前格式相同的数据时,它显示错误。我用','设置分隔符。错误:最后一个预期列 CONTEXT 之后的额外数据:COPY ca_manifest_checkpoint,第 2 行:“Canada,YYZ01A,YYZ01A_20170329_151501.txt,953353795858,31,,29/03/2017 14:57:55,30/03/2017 03:20: 02,,我……” 您是否有机会将表格与附加的持有人列一起导出,然后在持有人列被删除后重新导入? 这对我来说很奇怪。从长远来看,我每天都需要向表中导入新数据。每次都用这种方式做,不方便。 如果这是常规导入任务,并且您无法使数据源符合新的时间戳格式,您可能需要考虑使用 awk 使用一些脚本对文本数据进行预处理、sed等【参考方案4】:

用于将列的数据类型从 bigint 更改为 timestamp(for epoch to timestamp)

alter table <tablename> alter column <columnname> type timestamp without time zone using to_timestamp(<columnname>) AT TIME ZONE 'UTC';

例如;

alter table AB alter column col type timestamp without time zone using to_timestamp(col) AT TIME ZONE 'UTC';

用于将列的数据类型从时间戳更改为大整数(用于将时间戳更改为纪元)

alter table <tablename> alter column <columnname> type bigint using extract(EPOCH from <columnname>);

例如;

alter table AB alter column col type bigint using extract(EPOCH from col);

【讨论】:

以上是关于postgreSQL 将列数据类型更改为没有时区的时间戳的主要内容,如果未能解决你的问题,请参考以下文章

将列类型从整数更改为字符串

Postgresql以通用方式将列更改为行

Sequelize:将列类型更改为 ENUM

访问 SQL - 将列更改为自动编号?

Oracle SQL 在包含数据时将列类型从数字更改为 varchar2

SQL Server 2012 如何将列的数据类型从位更改为日期字段?