是否可以在 MySQL 中创建具有 UNIX_TIMESTAMP 默认值的列?

发布于 2024-10-22 19:49:44 字数 235 浏览 2 评论 0原文

我正在尝试这样做,但 MySQL 似乎不允许我这样做。这个问题有解决方案吗?或者我是否希望始终在 INSERT 查询中包含该函数?

CREATE TABLE foo(
  created INT NOT NULL DEFAULT UNIX_TIMESTAMP()
)

我知道 TIMESTAMP 类型接受 CURRENT_TIMESTAMP 默认值,但我的客户坚持在数据库中使用纪元时间。

I'm trying to do this, but it seems like MySQL isn't allowing me. Is there a solution to this issue or am I expected to always include the function in my INSERT queries?

CREATE TABLE foo(
  created INT NOT NULL DEFAULT UNIX_TIMESTAMP()
)

I'm aware of the TIMESTAMP type that accepts a CURRENT_TIMESTAMP default, but my client insisted on using epoch time in the database.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

彩扇题诗 2024-10-29 19:49:44

MySQL 实现TIMESTAMP 数据类型的方式,实际上是将纪元时间存储在数据库中。因此,如果您想将其显示为 CURRENT_TIMESTAMP,则只需使用默认值为 CURRENT_TIMESTAMPTIMESTAMP 列,然后对其应用 UNIX_TIMESTAMP() 即可。 int:

CREATE TABLE foo(
  created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

insert into foo values (current_Date()),(now());

select unix_timestamp(created) from foo;
+-------------------------+
| unix_timestamp(created) |
+-------------------------+
|              1300248000 |
|              1300306959 |
+-------------------------+
2 rows in set (0.00 sec)

但是,如果您确实希望列的数据类型为 INT,您可以使用 R. Bemrose 的建议并通过触发器设置它:

CREATE TABLE foo(
  created INT NULL
);

delimiter $

create trigger tr_b_ins_foo before insert on foo for each row
begin
  if (new.created is null)
  then
    set new.created = unix_timestamp();
  end if;
end $

delimiter ;


insert into foo values (unix_timestamp(current_Date())), (null);

select created from foo;
+------------+
| created    |
+------------+
| 1300248000 |
| 1300306995 |
+------------+
2 rows in set (0.00 sec)

The way MySQL implements the TIMESTAMP data type, it is actually storing the epoch time in the database. So you could just use a TIMESTAMP column with a default of CURRENT_TIMESTAMP and apply the UNIX_TIMESTAMP() to it if you want to display it as an int:

CREATE TABLE foo(
  created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

insert into foo values (current_Date()),(now());

select unix_timestamp(created) from foo;
+-------------------------+
| unix_timestamp(created) |
+-------------------------+
|              1300248000 |
|              1300306959 |
+-------------------------+
2 rows in set (0.00 sec)

However, if you really want the datatype of the column to be INT, you can use R. Bemrose's suggestion and set it via trigger:

CREATE TABLE foo(
  created INT NULL
);

delimiter $

create trigger tr_b_ins_foo before insert on foo for each row
begin
  if (new.created is null)
  then
    set new.created = unix_timestamp();
  end if;
end $

delimiter ;


insert into foo values (unix_timestamp(current_Date())), (null);

select created from foo;
+------------+
| created    |
+------------+
| 1300248000 |
| 1300306995 |
+------------+
2 rows in set (0.00 sec)
街角卖回忆 2024-10-29 19:49:44

来自文档

除了一个例外,默认值
必须是一个常数;它不可能是一个
函数或表达式。这意味着,
例如,您不能设置
日期列的默认值是
函数的值,例如 NOW() 或
当前_日期。例外的是
您可以将 CURRENT_TIMESTAMP 指定为
TIMESTAMP 列的默认值。

From the documentation:

With one exception, the default value
must be a constant; it cannot be a
function or an expression. This means,
for example, that you cannot set the
default for a date column to be the
value of a function such as NOW() or
CURRENT_DATE. The exception is that
you can specify CURRENT_TIMESTAMP as
the default for a TIMESTAMP column.

烂人 2024-10-29 19:49:44

您可以为此创建触发器。

用于插入

  • 查询

在 {table_name} FOR EACH ROW SET INSERT 之前创建触发器 {trigger_name} new.{field_name} = UNIX_TIMESTAMP(NOW());

  • 在这种情况下

在插入 foo 之前为每个行集创建触发器 my_trigger_name_1 new.created = UNIX_TIMESTAMP(NOW());

更新

  • 查询

在更新 {table_name} 之前创建触发器 {trigger_name} FOR EACH ROW SET new.{field_name} = UNIX_TIMESTAMP(NOW());

  • 在这种情况下

在更新 foo 之前为每个行集创建触发器 my_trigger_name_2 new.created = UNIX_TIMESTAMP(NOW());

注意:我不知道MYSQL TRIGGER的性能

请浏览这些链接

  1. 确定实现sql server触发器

  2. 使用触发器

You can create triggers for this.

for insertion

  • query

CREATE TRIGGER {trigger_name} BEFORE INSERT ON {table_name} FOR EACH ROW SET new.{field_name} = UNIX_TIMESTAMP(NOW());

  • in this case

CREATE TRIGGER my_trigger_name_1 BEFORE INSERT ON foo FOR EACH ROW SET new.created = UNIX_TIMESTAMP(NOW());

for update

  • query

CREATE TRIGGER {trigger_name} BEFORE UPDATE ON {table_name} FOR EACH ROW SET new.{field_name} = UNIX_TIMESTAMP(NOW());

  • in this case

CREATE TRIGGER my_trigger_name_2 BEFORE UPDATE ON foo FOR EACH ROW SET new.created = UNIX_TIMESTAMP(NOW());

Note : I have no idea about the performance of MYSQL TRIGGER

Please go through these links

  1. Identify some of the drawback of implementing sql server triggers

  2. Using Triggers

厌味 2024-10-29 19:49:44

正如 ktretyak 的回答,使用 MySQL v8+,您可以使用括号来做到这一点。

CREATE TABLE foo(
  created INT NOT NULL DEFAULT (UNIX_TIMESTAMP())
)

一些插入后,您可以看到它工作正常。
(在 MySQL 8.0.26 上测试 + 仅修补文本颜色)

tested case

或者,您也可以使用表达式。
检查ktretyak的回答

我写这个答案而不是评论或编辑答案(尝试并拒绝)
由于缺乏声誉,现在使用括号是一个很好的解决方案。

As ktretyak's answer, with MySQL v8+, you can do that using a parentheses.

CREATE TABLE foo(
  created INT NOT NULL DEFAULT (UNIX_TIMESTAMP())
)

After some inserts, you can see it works correctly.
(Tested on MySQL 8.0.26 + only text color patched)

tested case

Alternatively you can use an expression, too.
Check ktretyak's answer.

I write this answer instead of comment or edit answer(tried and rejected)
because of lack of REPUTATION and using a parentheses is good solution now.

吃素的狼 2024-10-29 19:49:44

好吧,如果 MySQL 不允许您直接执行此操作,您始终可以使用 BEFORE INSERT...FOR EACH ROW 触发器

Well, if MySQL won't let you do it directly, you can always do it using a BEFORE INSERT... FOR EACH ROW trigger.

乖乖哒 2024-10-29 19:49:44

现在,使用 MySQL v8+,您只需在括号中即可执行此操作:

CREATE TABLE t1 (
  -- literal defaults
  i INT         DEFAULT 0,
  c VARCHAR(10) DEFAULT '',
  -- expression defaults
  f FLOAT       DEFAULT (RAND() * RAND()),
  b BINARY(16)  DEFAULT (UUID_TO_BIN(UUID())),
  d DATE        DEFAULT (CURRENT_DATE + INTERVAL 1 YEAR),
  p POINT       DEFAULT (Point(0,0)),
  j JSON        DEFAULT (JSON_ARRAY())
);

请参阅 文档

Now, with MySQL v8+, you can to do this just in parentheses:

CREATE TABLE t1 (
  -- literal defaults
  i INT         DEFAULT 0,
  c VARCHAR(10) DEFAULT '',
  -- expression defaults
  f FLOAT       DEFAULT (RAND() * RAND()),
  b BINARY(16)  DEFAULT (UUID_TO_BIN(UUID())),
  d DATE        DEFAULT (CURRENT_DATE + INTERVAL 1 YEAR),
  p POINT       DEFAULT (Point(0,0)),
  j JSON        DEFAULT (JSON_ARRAY())
);

See docs

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文