【问题标题】:PostgreSQL => ALTER TABLE without timezone -> with timezone, using select for TZPostgreSQL => ALTER TABLE without timezone -> with timezone, using select for TZ
【发布时间】:2019-03-05 15:45:35
【问题描述】:

我正在尝试转换列,并将数据保留在指定时区。我有一个脚本,但最后在SELECT 上出错。

ALTER TABLE schema.table 
ALTER COLUMN column_date TYPE TIMESTAMP WITH TIME ZONE
USING column_date AT TIME ZONE (SELECT value FROM schema.table WHERE id = 'timezone');

ERROR:  cannot use subquery in transform expression

我存储了时区,但试图将其拉回以应用于脚本是一个挑战。我知道我可以简单地将时区硬编码为“EST|CST|PST”等,但我有多个需要应用的数据库(每个数据库有多个更改),因此最后需要SELECT。有没有办法做到这一点?

我已经就这个主题提出了几个问题;虽然有些接近,但它们并不完全满足需求(如果这是重复的,我很抱歉,我花了一段时间寻找答案)。

[已解决]:使用 2 个单独的查询

ALTER TABLE schema.table 
ALTER COLUMN column_date TYPE TIMESTAMP WITH TIME ZONE;

UPDATE schema.table 
SET column_date = column_date AT TIME ZONE 
    (SELECT value FROM schema.table WHERE id = 'timezone');

【问题讨论】:

    标签: postgresql alter-table


    【解决方案1】:

    您可以使用动态 SQL:

    DO
    $$BEGIN
       EXECUTE format('ALTER TABLE ... AT TIME ZONE %L',
                      (SELECT value FROM atable ...));
    END;$$;
    

    【讨论】:

    • 我确实喜欢这种方法,不幸的是这对我不起作用:错误:在“$$BEGIN”或附近未终止的美元引号字符串。这是用于 Postgres 的吗?
    • 我搞砸了,对不起。固定。
    • 效果很好,谢谢。但是,有没有办法在没有 BEGIN/END 的情况下做到这一点?由于我需要通过迁移脚本一次性运行其中的多个,并且按照规范,我不能使用 BEGIN/END/DECLARE/etc...
    • 那不是事务的BEGINEND,而是一个PL/pgSQL 块。整个就是一条SQL语句,会和周围的代码在同一个事务中运行。
    • 明白了,该命令存储在一个数据库中,但可以针对其他数据库运行。结果我们无法使用它们。一旦我有足够的代表,我会回来支持你的答案,我确实觉得它很有帮助,我非常感谢你的帮助。
    猜你喜欢
    • 2019-01-28
    • 2021-07-04
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 2022-12-02
    • 2014-08-22
    • 1970-01-01
    相关资源
    最近更新 更多