将MySQL与下表配合使用:

CREATE TABLE participants (
    id INT AUTO_INCREMENT PRIMARY KEY,
    puuid CHAR(36) NOT NULL,
    data JSON,
    project INT GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(data, '$.project'))) STORED NULL,
    schoolCode VARCHAR(255) GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(data, '$.schoolCode'))) STORED,
    UNIQUE KEY (puuid)
);

当我试着跑的时候:

insert into participants(puuid,data) values('aasd','{"project":1}');

它解决了一个问题 但当我try 的时候

insert into participants(puuid,data) values('aasd1','{"project":null}');

我收到一个错误,内容是:

Error Code: 1366. Incorrect integer value: 'null' for column 'project' at row 1

我又查了一遍

 show columns from participants;

它会返回

Results of show columns

为什么它不允许JSON对项目具有空值,即使它声明项目列允许空值?

除了这样的解决方案之外,没有其他解决方案了吗:

project INT GENERATED ALWAYS AS (COALESCE(JSON_UNQUOTE(JSON_EXTRACT(data, '$.project')), 0)) STORED NULL,

最新情况: 实际上似乎两者都不是

 project INT GENERATED ALWAYS AS (COALESCE(JSON_UNQUOTE(JSON_EXTRACT(data, '$.project')), 0)) STORED NULL,

也不是

 project INT GENERATED ALWAYS AS (IFNULL(JSON_UNQUOTE(JSON_EXTRACT(data, '$.project')), 0)) STORED NULL,

工作. 我即将放弃这个生成专栏的 idea .

推荐答案

缺少的JSON键提取为SQL NULL.

mysql> select json_extract('{"project":null}', '$.xyzzy') is null as is_it_null;
+------------+
| is_it_null |
+------------+
|          1 |
+------------+

JSON null值不会提取到SQL NULL.它提取为标量值'null'的JSON文档.

mysql> select json_extract('{"project":null}', '$.project') is null as is_it_null;
+------------+
| is_it_null |
+------------+
|          0 |
+------------+

JSON_UNQUOTE()不会将JSON值'null'转换为SQL NULL.它将其转换为SQL字符串值'null'.

mysql> select json_unquote(json_extract('{"project":null}', '$.project')) is null as is_it_null;
+------------+
| is_it_null |
+------------+
|          0 |
+------------+

因此,您生成的列try 解析字符串值'null'以将其转换为整数,这在严格模式下失败(默认设置):

mysql> select cast('null' as signed) as bad_integer;
+-------------+
| bad_integer |
+-------------+
|           0 |
+-------------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Truncated incorrect INTEGER value: 'null'

您可以通过将该字符串值与'null'进行比较并将SQL NULL替换为以下方式来修复它:

mysql> select nullif(json_unquote(json_extract('{"project":null}', '$.project')), 'null') is null as is_it_null;
+------------+
| is_it_null |
+------------+
|          1 |
+------------+

但是这不能与JSON字符串值'null'区分开来:

mysql> select nullif(json_unquote(json_extract('{"project":"null"}', '$.project')), 'null') is null as is_it_null;
+------------+
| is_it_null |
+------------+
|          1 |
+------------+

基本上,JSON在与SQL结合时是一团乱七八糟的东西.有如此多的边缘情况以违反直觉的方式运行,我不得不说这是多年来添加到SQL中的最糟糕的功能.

Mysql相关问答推荐

括号在SQL查询中的作用?

找出同一表中列A中的每个值在列B中出现的次数

从单行中获取最大日期的最佳方法

如何将多个字符串插入变量

如何使用等于、喜欢和不等于在 json 字段上编写查询?

在 MySQL 中使用非空条件 LAG() 函数

如何查找列的所有值都相同的行?

将sql查询转换为sequelize

如何获取从开始时间到结束时间的所有正在运行的作业(job)的总和?

Django中的MYSQL查询等效

MySQL 1292 截断不正确的日期时间值:'2020-09-11T08:32-50Z'

在 SQL 中将列添加为 End_date,间隔为 +100 天

如何查询打印已售罄的产品? [MYSQL]

如何将表的链接列转换为 SQL 中的行?

在 MySQL 中,我应该 Select 哪种排序规则?

MySQL触发器在某些条件下防止INSERT

utf8mb4_unicode_ci 与 utf8mb4_bin

WHERE 子句中的条件顺序会影响 MySQL 性能吗?

Python 是否支持 MySQL 准备好的语句?

为什么在 MySQL 中使用外键约束?