函数内的时间戳比较
Timestamp Comparison within Function
为了防止旧版本覆盖新版本,在这个简单的函数中:
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 并且右边多了 3 个数字。
如何在 UTC 和相同精度下进行比较?
您应该使用 timestamptz
(timestamp with time zone
) 而不是 timestamp
(timestamp without time zone
) 以避免任何时区混淆.在table中,在函数中,在整个食物链中。值始终在内部存储为 UTC 时间,并且比较会自动正确工作(比较独立于时区的时间点)。
参见:
- Ignoring time zones altogether in Rails and PostgreSQL
无论哪种方式,两种类型都具有 微秒 分辨率,即 6 小数位数。您的第一个示例以某种方式被截断了,可能是您的客户在显示中截断了。
完整答案如下:
- 使用
tz
= 时间戳 with
时区定义列。
tz
总是为客户提供 UTC 值,例如我正在使用 node/pg-promise,前端是 Angular/TS,它们都得到像 2021-04-17T22:42:57.610Z
这样的值。
- UTC 输出,UTC 提交回来(假设您不触及时间戳),是否足够好?是和否。如果您的客户端支持 6 位数字 十进制秒,则可以,否则对于 JavaScript 及其变体不支持,因为它仅支持 3 位数字。
- 解决办法是四舍五入到两位数然后比较
if (select tableTimestamp::timestamp(2) = parameter::timestamp(2) from mytable where ...) then Update mytable ...; else raise exception ...; end if;
P.S., with
和 without time zone
令人困惑。
为了防止旧版本覆盖新版本,在这个简单的函数中:
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 并且右边多了 3 个数字。
如何在 UTC 和相同精度下进行比较?
您应该使用 timestamptz
(timestamp with time zone
) 而不是 timestamp
(timestamp without time zone
) 以避免任何时区混淆.在table中,在函数中,在整个食物链中。值始终在内部存储为 UTC 时间,并且比较会自动正确工作(比较独立于时区的时间点)。
参见:
- Ignoring time zones altogether in Rails and PostgreSQL
无论哪种方式,两种类型都具有 微秒 分辨率,即 6 小数位数。您的第一个示例以某种方式被截断了,可能是您的客户在显示中截断了。
完整答案如下:
- 使用
tz
= 时间戳with
时区定义列。 tz
总是为客户提供 UTC 值,例如我正在使用 node/pg-promise,前端是 Angular/TS,它们都得到像2021-04-17T22:42:57.610Z
这样的值。- UTC 输出,UTC 提交回来(假设您不触及时间戳),是否足够好?是和否。如果您的客户端支持 6 位数字 十进制秒,则可以,否则对于 JavaScript 及其变体不支持,因为它仅支持 3 位数字。
- 解决办法是四舍五入到两位数然后比较
if (select tableTimestamp::timestamp(2) = parameter::timestamp(2) from mytable where ...) then Update mytable ...; else raise exception ...; end if;
P.S., with
和 without time zone
令人困惑。