可以将一个列安全地分配给自动更新的列的值吗?

huangapple go评论54阅读模式
英文:

can I safely assign a column to the value of an automatically updated column?

问题

如果列active从False更改为True,我还想将activated_at更改为与updated_at相同的值。查询将使用新的post-on update值还是旧值,或者行为未定义?

英文:

my updated_at column is set to current timestame ON UPDATE.

If the column active was False and is changed to True, I also want to change activated_at to be the same value as updated_at.

will the query

UPDATE mytable
SET active=TRUE, activated_at=mytable.updated_at
WHERE active=FALSE;

use the new post-on update value of updated_at, or the old one, or is the behavior undefined?

答案1

得分: 1

I suppose a simple test will probably get the answer faster for you than asking.

create table mytable(active bool, activated_at datetime, updated_at timestamp);
insert mytable values
(false,'2023-01-01 11:11:11',default),
(true,'2023-01-03 12:11:11',default),
(false,'2023-01-05 12:21:11',default);

select * from mytable;
+--------+---------------------+---------------------+
| active | activated_at        | updated_at          |
+--------+---------------------+---------------------+
|      0 | 2023-01-01 11:11:11 | 2023-05-17 01:45:11 |
|      1 | 2023-01-03 12:11:11 | 2023-05-17 01:45:11 |
|      0 | 2023-01-05 12:21:11 | 2023-05-17 01:45:11 |
+--------+---------------------+---------------------+

Let's try your query:

UPDATE mytable
SET active=TRUE, activated_at=mytable.updated_at
WHERE active=FALSE;

select * from mytable;
+--------+---------------------+---------------------+
| active | activated_at        | updated_at          |
+--------+---------------------+---------------------+
|      1 | 2023-05-17 01:45:11 | 2023-05-17 01:47:28 |
|      1 | 2023-01-03 12:11:11 | 2023-05-17 01:45:11 |
|      1 | 2023-05-17 01:45:11 | 2023-05-17 01:47:28 |
+--------+---------------------+---------------------+

As demonstrated above, the updated rows are using the OLD values before the timestamp auto-update kicks in. To circumvent that, we can simply set the value to the current datetime:

-- Let's truncate/insert the table and do it all over again.
select * from mytable;
+--------+---------------------+---------------------+
| active | activated_at        | updated_at          |
+--------+---------------------+---------------------+
|      0 | 2023-01-01 11:11:11 | 2023-05-17 01:54:31 |
|      1 | 2023-01-03 12:11:11 | 2023-05-17 01:54:31 |
|      0 | 2023-01-05 12:21:11 | 2023-05-17 01:54:31 |
+--------+---------------------+---------------------+

Here is the slightly modified query:

UPDATE mytable
SET active=TRUE, activated_at=current_timestamp()
WHERE active=FALSE;

select * from mytable;
+--------+---------------------+---------------------+
| active | activated_at        | updated_at          |
+--------+---------------------+---------------------+
|      1 | 2023-05-17 01:56:11 | 2023-05-17 01:56:11 |
|      1 | 2023-01-03 12:11:11 | 2023-05-17 01:54:31 |
|      1 | 2023-05-17 01:56:11 | 2023-05-17 01:56:11 |
+--------+---------------------+---------------------+

That's it.

英文:

I suppose a simple test will probably get the answer faster for you than asking.

create table mytable(active bool,activated_at datetime,updated_at timestamp);
insert mytable values
(false,'2023-01-01 11:11:11',default),
(true,'2023-01-03 12:11:11',default),
(false,'2023-01-05 12:21:11',default);

select * from mytable;
+--------+---------------------+---------------------+
| active | activated_at        | updated_at          |
+--------+---------------------+---------------------+
|      0 | 2023-01-01 11:11:11 | 2023-05-17 01:45:11 |
|      1 | 2023-01-03 12:11:11 | 2023-05-17 01:45:11 |
|      0 | 2023-01-05 12:21:11 | 2023-05-17 01:45:11 |
+--------+---------------------+---------------------+

Let's try your query:

UPDATE mytable
SET active=TRUE, activated_at=mytable.updated_at
WHERE active=FALSE;

select * from mytable;                                                   
+--------+---------------------+---------------------+
| active | activated_at        | updated_at          |
+--------+---------------------+---------------------+
|      1 | 2023-05-17 01:45:11 | 2023-05-17 01:47:28 |
|      1 | 2023-01-03 12:11:11 | 2023-05-17 01:45:11 |
|      1 | 2023-05-17 01:45:11 | 2023-05-17 01:47:28 |
+--------+---------------------+---------------------+

As demonstrated above, the updated rows are using the OLD values before the timestamp auto-update kicks in. To circumvent that, we can simply set the value to the current datetime:

-- Let's truncate/insert the table and do it all over again.
 select * from mytable;                                                   
+--------+---------------------+---------------------+
| active | activated_at        | updated_at          |
+--------+---------------------+---------------------+
|      0 | 2023-01-01 11:11:11 | 2023-05-17 01:54:31 |
|      1 | 2023-01-03 12:11:11 | 2023-05-17 01:54:31 |
|      0 | 2023-01-05 12:21:11 | 2023-05-17 01:54:31 |
+--------+---------------------+---------------------+

Here is the slightly modified query:

UPDATE mytable
SET active=TRUE, activated_at=current_timestamp()
WHERE active=FALSE;

 select * from mytable;
+--------+---------------------+---------------------+
| active | activated_at        | updated_at          |
+--------+---------------------+---------------------+
|      1 | 2023-05-17 01:56:11 | 2023-05-17 01:56:11 |
|      1 | 2023-01-03 12:11:11 | 2023-05-17 01:54:31 |
|      1 | 2023-05-17 01:56:11 | 2023-05-17 01:56:11 |
+--------+---------------------+---------------------+

That's it.

huangapple
  • 本文由 发表于 2023年5月17日 06:29:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76267467.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定