为什么在 MySQL 中使用 JSON_EXTRACT 时 0/false 返回 true

und*_*man 3 mysql query json mysql-8.0

我有一个条件来选择一个错误的 JSON 文档值。

我的行:

1. {"my_value": false}
2. {"my_value": 0}
3. {"my_value": "0"}
4. {"my_value": null}
5. {"my_value": true} // this one got selected
Run Code Online (Sandbox Code Playgroud)

我的查询:

SELECT * FROM my_table
WHERE JSON_UNQUOTE(JSON_EXTRACT(my_column, '$.my_value')) = false
Run Code Online (Sandbox Code Playgroud)

即使true有价值,第 5 行也会被选中。我怎样才能防止这种情况?

版本是 MySQL 8.0.25。

小智 7

希望你做得很好。

我想查看您的架构以确保一切正常。我试图重现我相信你所做的。

这是我所做的:

mysql> create database test295895;
mysql> use test295895;
mysql> create table my_table (my_column JSON);
Run Code Online (Sandbox Code Playgroud)

然后我插入了你显示的值:

mysql> insert into my_table VALUES('{"my_value": false}');
Query OK, 1 row affected (0.01 sec)

mysql> insert into my_table VALUES('{"my_value": 0}');
Query OK, 1 row affected (0.02 sec)

mysql> insert into my_table VALUES('{"my_value": "0"}');
Query OK, 1 row affected (0.02 sec)

mysql> insert into my_table VALUES('{"my_value": null}');
Query OK, 1 row affected (0.02 sec)

mysql> insert into my_table VALUES('{"my_value": true}');
Query OK, 1 row affected (0.01 sec)

mysql> select * from my_table;
+---------------------+
| my_column           |
+---------------------+
| {"my_value": false} |
| {"my_value": 0}     |
| {"my_value": "0"}   |
| {"my_value": null}  |
| {"my_value": true}  |
+---------------------+
5 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

然后我运行了你的查询,我看到了所有的结果:

mysql> SELECT * FROM my_table
    -> WHERE JSON_UNQUOTE(JSON_EXTRACT(my_column, '$.my_value')) = false
    -> ;
+---------------------+
| my_column           |
+---------------------+
| {"my_value": false} |
| {"my_value": 0}     |
| {"my_value": "0"}   |
| {"my_value": null}  |
| {"my_value": true}  |
+---------------------+
5 rows in set, 3 warnings (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

我决定看看 JSON_EXTRACT 返回了什么:

mysql> SELECT JSON_UNQUOTE(JSON_EXTRACT(my_column, '$.my_value')) from my_table;
+-----------------------------------------------------+
| JSON_UNQUOTE(JSON_EXTRACT(my_column, '$.my_value')) |
+-----------------------------------------------------+
| false                                               |
| 0                                                   |
| 0                                                   |
| null                                                |
| true                                                |
+-----------------------------------------------------+
5 rows in set (0.00 sec)

mysql> SELECT JSON_UNQUOTE(JSON_EXTRACT(my_column, '$.my_value')) from my_table WHERE JSON_UNQUOTE(JSON_EXTRACT(my_column, '$.my_value')) = false;
+-----------------------------------------------------+
| JSON_UNQUOTE(JSON_EXTRACT(my_column, '$.my_value')) |
+-----------------------------------------------------+
| false                                               |
| 0                                                   |
| 0                                                   |
| null                                                |
| true                                                |
+-----------------------------------------------------+
5 rows in set, 3 warnings (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

因此,至少在我的情况下,似乎返回的所有内容都作为字符串返回,因此我没有与布尔值进行比较,而是与 'false' 进行了比较:

mysql> SELECT JSON_UNQUOTE(JSON_EXTRACT(my_column, '$.my_value')) from my_table WHERE JSON_UNQUOTE(JSON_EXTRACT(my_column, '$.my_value')) = 'false';
+-----------------------------------------------------+
| JSON_UNQUOTE(JSON_EXTRACT(my_column, '$.my_value')) |
+-----------------------------------------------------+
| false                                               |
+-----------------------------------------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

它奏效了。所以也许你可以测试你是否与'false' VARCHAR 而不是 Boolean 进行比较它是否有效?

干杯。