使用 rand() 函数将计算列添加到现有表中

问题描述

我有一个已存在的表product,想添加一个新的计算列test,公式为SUBSTRING(MD5(RAND()) FROM 1 FOR 16)

所以查询是这样的:

alter table product add test varchar(255) as (SUBSTRING(MD5(RAND()) FROM 1 FOR 16));

但它返回给我的错误

Error Code: 3763. Expression of generated column 'test' contains a disallowed function: rand.

有人知道为什么以及如何解决吗?

解决方法

正如其他人在评论中所述,您不能在计算列中使用 RAND()。但是您可以使用触发器获得相同的预期结果。

首先,添加列(我称之为 test_md5rand):

ALTER TABLE product add test_md5rand varchar(255);

然后添加触发器:

CREATE TRIGGER product_md5
BEFORE INSERT
ON product FOR EACH ROW
BEGIN
  SET NEW.test_md5rand = SUBSTRING(MD5(RAND()) FROM 1 FOR 16);
END

也许更新现有的行:

UPDATE product
   SET test_md5rand = SUBSTRING(MD5(RAND()) FROM 1 FOR 16)
 WHERE test_md5rand IS NULL;

dbfiddle

,

您不能将值添加为计算列——原因很简单:每次执行时值都会发生变化。从技术上讲,这是因为 rand() 是一个 volatile 函数。

如果你真的想要这个功能,你可以使用一个视图:

create view v_product as
    select p.*,left(md5(rand()),16) as test
    from product p;

拥有可改变的价值可能不是您想要的。正如另一个答案所暗示的那样,您可以使用触发器。在我看来,这也是令人不快的。

一种选择是将计算值基于现有列,例如名称:

alter table product add test varchar(16) as left(md5(product_name),16);

这种方法唯一可能的缺点是,如果列发生变化,那么 test 也会发生变化。