无法将列的类型从日期更改为整数

0qx6xfy6  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(390)

我目前正在尝试使用这里找到的解决方案,但我似乎无法更改用户列的类型 dateinteger .
当我尝试时:

ALTER TABLE users ALTER COLUMN password_reset_expires TYPE integer;

我得到这个错误:

ERROR:  column "password_reset_expires" cannot be cast automatically to type integer
HINT:  You might need to specify "USING password_reset_expires::integer".

当我尝试时:

ALTER TABLE users ALTER COLUMN password_reset_expires TYPE integer
USING (password_reset_expires::integer);

错误告诉我:

ERROR:  cannot cast type date to integer
LINE 1: ...expires TYPE integer USING (password_reset_expires::integer)...

我的表定义:

Table "public.users"
         Column         |          Type          | Collation | Nullable |              Default
------------------------+------------------------+-----------+----------+-----------------------------------
 id                     | bigint                 |           | not null | nextval('users_id_seq'::regclass)
 name                   | character varying(20)  |           | not null |
 email                  | character varying(100) |           | not null |
 password               | character varying(500) |           | not null |
 password_changed_at    | date                   |           |          |
 password_reset_token   | character varying(300) |           |          |
 password_reset_expires | date                   |           |          |
Indexes:
    "users_pkey" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "tokens" CONSTRAINT "tokens_token_pk_fkey" FOREIGN KEY (fk_users_id) REFERENCES users(id)

以下是我的一个用户对象:

{
  id: '59',
  name: 'visitor',
  email: 'visitor',
  password: '$2b$10$0UGgdRUlXFYeQfk5Nv/vXe9khdzyyOqsTiFGyNXLfEDuOFAt0xc1G',
  password_changed_at: null,
  password_reset_token: null,
  password_reset_expires: null
}
jxct1oxe

jxct1oxe1#

基本上,使用sql标准函数 EXTRACT() . 您的意见:
我要存储的内容 password_reset_expires 以及 password_changed_at 是1594329364292这样的数字吗
... 表示要将自unix epoch 1970-01-01 00:00:00以来的毫秒数存储为整数值。但这超出了类型的范围 integer (签名) int4 ),最多允许2^31-1=2147483647。在撰写本文时,自纪元以来已经过了1594335691272毫秒。
将秒存储在 integer 列:

ALTER TABLE users ALTER COLUMN password_reset_expires TYPE integer
USING (EXTRACT(EPOCH FROM password_reset_expires)::int);

或将毫秒存储在 bigint
(签名) int8 ,最多允许2^63-1=9223372036854775807):

ALTER TABLE users ALTER COLUMN password_reset_expires TYPE bigint -- !
USING (EXTRACT(EPOCH FROM password_reset_expires)::bigint * 1000);
``` `EXTRACT(EPOCH FROM ...)` 根据手册返回:
为了 `timestamp with time zone` 值,自1970-01-01 00:00:00 utc以来的秒数(可以为负);为了 `date` 以及 `timestamp` 值,自本地时间1970-01-01 00:00:00以来的秒数;为了 `interval` 值,间隔中的总秒数
因为源头是 `date` 在这种情况下,不可能有分数秒,我们可以乘以1000得到毫秒数。
再说一次,如果没有毫秒,为什么要存储毫秒数呢?
更重要的是,为什么不保留 `date` ? 如果值实际表示日期,则数据类型 `date` 几乎可以肯定是最好的选择。

相关问题