【问题标题】:Timestamp Comparison within Function函数内的时间戳比较
【发布时间】:2021-07-11 22:25:15
【问题描述】:

为了防止旧版本覆盖新版本,在这个简单的函数中:

create function myupdate(paramts timestamp without time zone, ...)
  language plpgsql AS
$$
begin
-- step 1 compare current record timestamp vs. supplied timestamp
if exists (select 1 from record where ts <> paramts and ...) then
    raise exception 'A newer version exists, cannot update.';
end if;
...
end
$$;

ts 定义与timestamp without time zone 相同。

paramts 值由函数提供:

create function myfetch(...)
  language plpgsql AS
$$
begin
    return query select ts, ... from record where ...;
end
$$;

节点 API 和 Angular 客户端 UI 获得的是 2021-04-16T21:37:35.878Z,提交给 myupdate() 的值也是如此。但是,在我们的一台西海岸服务器上,在 myupdate() 内部执行期间,ts 会自动转换为 PST 2021-04-16 14:37:35.878694 并在对。

如何比较 UTC 和相同精度?

【问题讨论】:

    标签: postgresql timezone


    【解决方案1】:

    您应该使用 timestamptz (timestamp with time zone) 而不是 timestamp (timestamp without time zone) 以避免任何时区混淆。在表中,在功能中,在整个食物链中。值总是在内部存储为 UTC 时间,并且比较会自动正确地进行(比较独立于时区的时间点)。

    见:

    无论哪种方式,这两种类型都具有 微秒 分辨率,即 6 派系十进制数字。您的第一个示例以某种方式被截断,可能是您的客户端在显示中。

    【讨论】:

    • 感谢 Erwin 的建议,即使答案没有回答我所有的问题,我仍然接受它,因为 tz 是最好的解决方案。我将在下面发布我的完整答案和解决方案。
    【解决方案2】:

    这是完整的答案:

    1. 使用tz = 时间戳with 列定义时区。
    2. tz 总是为客户端提供 UTC 值,例如我使用的是 node/pg-promise,前端是 Angular/TS,它们都得到像 2021-04-17T22:42:57.610Z 这样的值。
    3. UTC 输出,UTC 提交回来(假设您不触摸时间戳),是否足够好?是和否。如果您的客户端支持 6 位十进制秒,则是,否则 JavaScript 和变体则否,因为它仅支持 3 位。
    4. 解决方案是四舍五入到 2 位,然后比较

    if (select tableTimestamp::timestamp(2) = parameter::timestamp(2) from mytable where ...) then Update mytable ...; else raise exception ...; end if;

    P.S.,withwithout time zone 令人困惑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 2020-10-10
      • 2016-07-26
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多