问题描述
我有一个已存在的表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;
,
您不能将值添加为计算列——原因很简单:每次执行时值都会发生变化。从技术上讲,这是因为 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
也会发生变化。