update a VIRTUAL GENERATED column

最近写个搬数据脚本,发现报了个这样的错

3105, "The value specified for generated column '某字段' in table '某表' is not allowed."

研究后发现该字段是自动生成的(generated column),主动去添加肯定会报错。解决方案就是增、改时别动这个字段
参考:https://stackoverflow.com/questions/50667827/update-a-virtual-generated-column/50668208

延申

作为不怎么懂sql的前端,查阅了一波资料来了解数据库生成字段generated column(virtual column)的机制,也算了解一波mysql

mysql > create table mydbops_lab_test_1
(id int(11) NOT NULL AUTO_INCREMENT primary key,
Total_cost float(9,4),
Expensive float(9,4),
Balance_amount float(12,6) GENERATED ALWAYS AS (Total_cost - Expensive),
email_id varchar(25),
name varchar(30));
 Query OK, 0 rows affected (0.34 sec)

先上一波代码,上述代码中的Balance_amount字段就属于生成字段
GENERATED ALWAYS语句代表该字段是生成字段,其有两种模式:
VIRTUAL:只会在读取的时候拿到,不会存为字段
STORED:存为字段
定义的语法如代码所示,个人觉得需要注意的主要有两点:
1.子查询、变量、库函数和你自己写的函数不能用在表达式里
2.你可以用其他的生成字段来计算新的生成字段,但要注意你使用生成的字段要在前面声明过
另外说下生成字段主要的应用场景:你有一些复杂的查询(或者是常写的查询),此时写个生成字段,相当于进行一个封装;或者你的某些字段是JSON,查起来不方便。
文章有提到生成字段的缺点:生成字段会在column,index里面存两遍;将生成字段作为索引会带来一些问题(不是很懂MySQL,可自己读文章)
更多样例:

mysql > create table mydbops_lab_test_1
(id int(11) NOT NULL AUTO_INCREMENT primary key,
Total_cost float(9,4),
Expensive float(9,4),
Balance_amount float(12,6) GENERATED ALWAYS AS (Total_cost - Expensive),
email_id varchar(25),
name varchar(30));
 Query OK, 0 rows affected (0.34 sec)

mysql> desc mydbops_lab_test_1;
 +----------------+-------------+------+-----+---------+-------------------+
 | Field           | Type       | Null | Key | Default | Extra             |
 +----------------+-------------+------+-----+---------+-------------------+
 | id              | int(11)    | NO   | PRI | NULL    | auto_increment    |
 | Total_cost      | float(9,4) | YES  |     | NULL    |                   |
 | Expensive       | float(9,4) | YES  |     | NULL    |                   |
 | Balance_amount  | float(12,6)| YES  |     | NULL    | VIRTUAL GENERATED |
 | email_id        | varchar(25)| YES  |     | NULL    |                   |
 | name            | varchar(30)| NO   |     | NULL    |                   |
 +----------------+-------------+------+-----+---------+-------------------+
 6 rows in set (0.00 sec)
mysql> alter table mydbops_lab_test_1 add index idx_Balance_amount(Balance_amount);
 Query OK, 0 rows affected (0.33 sec)
 Records: 0 Duplicates: 0 Warnings: 0

mysql> show create table mydbops_lab_test_1\G
 *************************** 1. row ***************************
 Table: mydbops_lab_test_1
 Create Table: CREATE TABLE `mydbops_lab_test_1` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `Total_cost` float(9,4) DEFAULT NULL,
 `Expensive` float(9,4) DEFAULT NULL,
 `Balance_amount` float(12,6) GENERATED ALWAYS AS ((`Total_cost` - `Expensive`)) VIRTUAL,
 `email_id` varchar(25) DEFAULT NULL,
 `name` varchar(30) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `idx_Balance_amount` (`Balance_amount`)
 ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1
 1 row in set (0.00 sec)

参考:https://mydbops.wordpress.com/2017/07/19/virtual-columns-in-mysql-and-use-cases/

你可能感兴趣的:(update a VIRTUAL GENERATED column)