错误分析 一般来讲,找到对应的insert字段,然后看一下是否是由于字段类型不匹配导致的。 例如,表中声明的是bigInt类型,你传值传了个字符串进入。 另外,如果你是通过insert into select的方式,将查询结果导入到新的表中,可能你单独执行select中的内容,是可以查询到相应的结果,但是当你执行insert into语句时,会产生如下错误
1 |
1292. Truncated incorrect INTEGER value: '' |
在MySQL的论坛上找到一个哥们儿说的内容,也就是说这个1292的错误,有可能并不是错误,而是警告提示。可以通过ignore关键字进行警告屏蔽 所以,我把自己的代码前缀,改成如下格式,即可正常执行导入操作
1 |
INSERT ignore INTO t_XXX SELECT …… |
———————————————— 版权声明:本文为CSDN博主「小魏的马仔」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/xuexiiphone/article/details/103426404
View Details
1 2 3 |
SELECT GROUP_CONCAT(SUBSTRING_INDEX(SUBSTRING(JSON_EXTRACT(jsonArray,CONCAT('$[', help_topic_id, '].preName')),2),'"',1)) FROM mysql.help_topic WHERE help_topic_id<JSON_LENGTH(jsonArray) |
GROUP_CONCAT:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator '分隔符'] ) SUBSTRING_INDEX:substring_index(str,delim,count) str:要处理的字符串 delim:分隔符 count:计数 SUBSTRING:SUBSTRING(string,position) JSON_EXTRACT:取json字符串字段下的某个键的值
View Details前言: 在索引优化时,经常会看到的一句话:如果索引字段出现隐式字符集转换的话,那么索引将失效,进而转为全表扫描,查询效率将大大降低,要避免出现隐式字符集转换; 在此我想问问同学们: 大家知道为什么隐式字符集转换会导致索引失效吗? 实际场景中有没有遇到过隐式字符集转换导致索引失效的场景,具体排查的过程; 本文主线: 由上面的两个问题牵引出了本文的主线; 简单描述下隐式字符集转换导致索引失效的原因 然后模拟实际场景排查隐式字符集转换导致索引失效的过程 隐式字符集转换导致索引失效的原因 MySQL索引的数据结构是 B+Tree,想要走索引查询必须要满足其 最左前缀原则 ,否则无法通过索引树进行查找,只能进行全表扫描; 例如:下面的这个SQL由于在 索引字段 上使用函数进行运算,导致索引失效
1 |
select * from t_user where SUBSTR(name, 1, 2) = '李彤' |
上面的这个SQL怎么改造才能使索引生效呢?如下所示:
1 |
select * from t_user where name like '李彤%' |
通过上面的小例子可以知道,如果在索引字段上使用函数运算,则会导致索引失效,而索引字段的 隐式字符集转换 由于MySQL会自动的在索引字段上加上 转换函数 ,进而会导致索引失效; 那接下来我们就通过模拟的实际场景来具体看看是不是由于MySQL自动给加上了转换函数而导致索引失效的; 模拟场景 + 问题排查 由于导致索引失效的原因有很多,如果自己写的SQL怎么看都没问题,但是通过查看执行计划发现就是没有走索引查询,此时就会让很多人陷入困境,这到底是怎么导致的呢? 此时本文重点将要讲述的工具就要闪亮登场啦: explain extended + show warnings ; 使用这个工具可以将执行的SQL语句的一些扩展信息展示出来,这些扩展信息就包括:MySQL优化时可能会添加上字符集转换函数,使得字符集不匹配的SQL可以正确执行下去; 下面就来具体聊聊 explain extended + show warnings 的使用; 模拟隐式字符集转换的场景: 首先创建两个字符集不一样的表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
CREATE TABLE `t_department` ( `id` int(11) NOT NULL AUTO_INCREMENT, `de_no` varchar(32) NOT NULL, `info` varchar(200) DEFAULT NULL, `de_name` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_de_no` (`de_no`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4; CREATE TABLE `t_employees` ( `id` int(11) NOT NULL AUTO_INCREMENT, `em_no` varchar(32) NOT NULL, `de_no` varchar(32) NOT NULL, `age` int(11) DEFAULT NULL, `info` varchar(200) DEFAULT NULL, `em_name` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_em_no` (`de_no`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; |
然后使用存储过程构造数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# 如果存储过程存在则删除 DROP PROCEDURE IF EXISTS proc_initData; DELIMITER $ # 创建存储过程 CREATE PROCEDURE proc_initData() BEGIN DECLARE i INT DEFAULT 1; WHILE i<=30 DO # 新增数据 INSERT INTO t_employees ( em_no, de_no, info, em_name , age) VALUES ( CONCAT('001', i), '003', 'test11', 'test2', i ); #执行的sql语句 SET i = i+1; END WHILE; END $ # 调用存储过程 CALL proc_initData(); |
注意:在构造数据时,记得将 t_employees 表中的 de_no 字段值构造的 离散些 ,因为如果索引字段值的 区分度很低 的话,那么MyQSL优化器通过采样统计分析时,发现索引查询和全表扫描性能差不多,就会直接进行全表扫描了; 索引失效的查询SQL语句: 将表和数据构造完后,我们使用SQL语句进行查询下,然后再看看其执行计划;
1 2 |
explain select * from t_department a LEFT JOIN t_employees b on a.de_no = b.de_no where a.id = 16 |
其执行计划如下: 发现 t_employees 表中的 de_no 字段有索引,但是没有走索引查询,type=ALL 走的全表扫描,但是通过查看SQL语句发现其没有问题呀,表面看上去都是满足走索引查询的条件呀,排查到这发现遇到了困境,苦恼啊! 还好,通过在网络世界上遨游,最终发现了 explain extended + show warnings 利器,利用它快速发现了索引失效的根本原因,然后快速找到了解决方案; 下面就来聊聊这个利器的具体使用,开森! 使用利器快速排查问题: 注意:explain 后面跟的关键字 EXTENDED(扩展信息) 在MySQL5.7及之后的版本中废弃了,但是该语法仍被识别为向后兼容,所以在5.7版本及后续版本中,可以不用在 explain 后面添加 EXTENDED 了; EXTENDED关键字的具体查阅资料:https://dev.mysql.com/doc/refman/5.7/en/explain-extended.html 具体使用方法如下: ①、首先在MySQL的可视化工具中打开一个 命令列介面 :工具 --> 命令列介面 ②、然后输入下面的SQL并按回车:
1 2 |
explain EXTENDED select * from t_department a LEFT JOIN t_employees b on a.de_no = b.de_no where a.id = 4019; |
③、然后紧接着输入命令 show warnings; 并回车,会出现如下图所示内容: 通过展示出的执行SQL扩展信息,发现MySQL在字符集不一致时自动添加上字符集转换函数,因为是在 索引字段 de_no 上添加的转换函数,所以就导致了索引失效; 而如果我们没看扩展信息的话,那么可能直到我们查看表结构的时候才会发现是由于字符集不一致导致的,这样就会花费很多的时间; 扩展:隐式类型转换 咱们聊完上面的隐式字符集转换导致索引失效的情况,再来简单聊聊另一种 隐式类型转换 导致索引失效的情况; […]
View Detailsmysql 批量更新如果一条条去更新效率是相当的慢, 循环一条一条的更新记录,一条记录update一次,这样性能很差,也很容易造成阻塞。 mysql 批量更新共有以下四种办法 1、.replace into 批量更新
1 |
replace into test_tbl (id,dr) values (1,'2'),(2,'3'),...(x,'y'); |
2、insert into …on duplicate key update批量更新
1 |
insert into test_tbl (id,dr) values (1,'2'),(2,'3'),...(x,'y') on duplicate key update dr=values(dr); |
3.创建临时表,先更新临时表,然后从临时表中update
1 2 3 |
create temporary table tmp(id int(4) primary key,dr varchar(50)); insert into tmp values (0,'gone'), (1,'xx'),...(m,'yy'); update test_tbl, tmp set test_tbl.dr=tmp.dr where test_tbl.id=tmp.id; |
注意:这种方法需要用户有temporary 表的create 权限。 4、使用mysql 自带的语句构建批量更新 mysql 实现批量 可以用点小技巧来实现:
1 2 3 4 5 6 7 |
UPDATE tableName SET orderId = CASE id WHEN 1 THEN 3 WHEN 2 THEN 4 WHEN 3 THEN 5 END WHERE id IN (1,2,3) |
这句sql 的意思是,更新orderId 字段,如果id=1 则orderId 的值为3,如果id=2 则orderId 的值为4…… where部分不影响代码的执行,但是会提高sql执行的效率。确保sql语句仅执行需要修改的行数,这里只有3条数据进行更新,而where子句确保只有3行数据执行。 如果更新多个值的话,只需要稍加修改:
1 2 3 4 5 6 7 8 9 10 11 12 |
UPDATE categories SET orderId = CASE id WHEN 1 THEN 3 WHEN 2 THEN 4 WHEN 3 THEN 5 END, title = CASE id WHEN 1 THEN 'New Title 1' WHEN 2 THEN 'New Title 2' WHEN 3 THEN 'New Title 3' END WHERE id IN (1,2,3) |
到这里,已经完成一条mysql语句更新多条记录了。 php中用数组形式赋值批量更新的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$display_order = array( 1 => 4, 2 => 1, 3 => 2, 4 => 3, 5 => 9, 6 => 5, 7 => 8, 8 => 9 ); $ids = implode(',', array_keys($display_order)); $sql = "UPDATE categories SET display_order = CASE id "; foreach ($display_order as $id => $ordinal) { $sql .= sprintf("WHEN %d THEN %d ", $id, $ordinal); } $sql .= "END WHERE id IN ($ids)"; echo $sql; |
这个例子,有8条记录进行更新。代码也很容易理解,你学会了吗 更新 100000条数据的性能就测试结果来看,测试当时使用replace into性能较好。 replace into 和 insert into on duplicate key update的不同在于: replace into 操作本质是对重复的记录先delete 后insert,如果更新的字段不全会将缺失的字段置为缺省值,用这个要悠着点否则不小心清空大量数据可不是闹着玩的。 insert into 则是只update重复记录,不会改变其它字段。 from:https://www.cnblogs.com/mslagee/p/6509682.html
View Details
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
using System; using System.Collections.Generic; using System.Configuration; using MySql.Data.MySqlClient; using System.Data; namespace Utils { /// <summary> /// MySQL数据库工具类 /// </summary> public abstract class MySQLUtil { /// <summary> /// 数据库连接字符串 /// </summary> public static readonly string ConnStr = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; /// <summary> /// 执行语句并返回影响的行数 /// </summary> /// <param name="connStr">数据库连接字符串</param> /// <param name="cmdType">命令类型</param> /// <param name="cmdText">命令字符串</param> /// <param name="parameters">参数集</param> /// <returns>影响的行数</returns> public static int ExecuteNonQuery(string connStr, CommandType cmdType, string cmdText, params MySqlParameter[] parameters) { using (var conn = new MySqlConnection(connStr)) { return ExecuteNonQuery(conn, cmdType, cmdText, parameters); } } /// <summary> /// 执行语句并返回影响的行数 /// </summary> /// <param name="conn">数据库连接</param> /// <param name="cmdType">命令类型</param> /// <param name="cmdText">命令字符串</param> /// <param name="parameters">参数集</param> /// <returns>影响的行数</returns> public static int ExecuteNonQuery(MySqlConnection conn, CommandType cmdType, string cmdText, params MySqlParameter[] parameters) { using (var cmd = new MySqlCommand()) { PrepareCommand(cmd, conn, null, cmdType, cmdText, parameters); var val = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return val; } } /// <summary> /// 执行语句并返回影响的行数 /// </summary> /// <param name="trans">事务</param> /// <param name="cmdType">命令类型</param> /// <param name="cmdText">命令字符串</param> /// <param name="parameters">参数集</param> /// <returns>影响的行数</returns> public static int ExecuteNonQuery(MySqlTransaction trans, CommandType cmdType, string cmdText, params MySqlParameter[] parameters) { using (var cmd = new MySqlCommand()) { PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, parameters); var val = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return val; } } /// <summary> /// 执行语句并返回DataReader对象 /// </summary> /// <param name="connStr">数据库连接字符串</param> /// <param name="cmdType">命令类型</param> /// <param name="cmdText">命令字符串</param> /// <param name="parameters">参数集</param> /// <returns>执行语句并返回DataReader对象</returns> /// <remarks>P.S:DataReader使用后要手动释放</remarks> public static MySqlDataReader ExecuteReader(string connStr, CommandType cmdType, string cmdText, params MySqlParameter[] parameters) { var cmd = new MySqlCommand(); var conn = new MySqlConnection(connStr); try { PrepareCommand(cmd, conn, null, cmdType, cmdText, parameters); var dr = cmd.ExecuteReader(CommandBehavior.CloseConnection); cmd.Parameters.Clear(); return dr; } catch { conn.Close(); throw; } } /// <summary> /// 执行语句并返回DataSet对象 /// </summary> /// <param name="cmdText"></param> /// <param name="parameters"></param> /// <returns></returns> public static DataSet ExecuteDataSet(string cmdText, params MySqlParameter[] parameters) { return ExecuteDataSet(ConnStr, CommandType.Text, cmdText, parameters); } /// <summary> /// 执行语句并返回DataSet对象 /// </summary> /// <param name="connStr">数据库连接字符串</param> /// <param name="cmdType">命令类型</param> /// <param name="cmdText">命令字符串</param> /// <param name="parameters">参数集</param> /// <returns>执行语句并返回DataSet对象</returns> /// <returns></returns> public static DataSet ExecuteDataSet(string connStr, CommandType cmdType, string cmdText, params MySqlParameter[] parameters) { using (var conn = new MySqlConnection(connStr)) { return ExecuteDataSet(conn, cmdType, cmdText, parameters); } } /// <summary> /// 执行语句并返回DataSet对象 /// </summary> /// <param name="connStr">数据库连接字符串</param> /// <param name="cmdType">命令类型</param> /// <param name="cmdText">命令字符串</param> /// <param name="parameters">参数集</param> /// <returns>执行语句并返回DataSet对象</returns> /// <returns></returns> public static DataSet ExecuteDataSet(MySqlConnection conn, CommandType cmdType, string cmdText, params MySqlParameter[] parameters) { using (var cmd = new MySqlCommand()) { PrepareCommand(cmd, conn, null, cmdType, cmdText, parameters); using (var da = new MySqlDataAdapter(cmd)) { var ds = new DataSet(); try { da.Fill(ds, "ds"); cmd.Parameters.Clear(); } catch (MySqlException ex) { throw new Exception(ex.Message); } return ds; } } } /// <summary> /// 执行语句并返回一个对象 /// </summary> /// <param name="cmdText">命令字符串</param> /// <param name="parameters">参数集</param> /// <returns>返回一个object对象,对象中只包含一列。</returns> public static object ExecuteScalar(string cmdText, params MySqlParameter[] parameters) { return ExecuteScalar(ConnStr, CommandType.Text, cmdText, parameters); } /// <summary> /// 执行语句并返回一个对象 /// </summary> /// <param name="connStr">数据库连接字符串</param> /// <param name="cmdType">命令类型</param> /// <param name="cmdText">命令字符串</param> /// <param name="parameters">参数集</param> /// <returns>返回一个object对象,对象中只包含一列。</returns> public static object ExecuteScalar(string connStr, CommandType cmdType, string cmdText, params MySqlParameter[] parameters) { using (var conn = new MySqlConnection(connStr)) { return ExecuteScalar(conn, cmdType, cmdText, parameters); } } /// <summary> /// 执行语句并返回一个对象 /// </summary> /// <param name="conn">数据库连接</param> /// <param name="cmdType">命令类型</param> /// <param name="cmdText">命令字符串</param> /// <param name="parameters">参数集</param> /// <returns>返回一个object对象,对象中只包含一列。</returns> public static object ExecuteScalar(MySqlConnection conn, CommandType cmdType, string cmdText, params MySqlParameter[] parameters) { using (var cmd = new MySqlCommand()) { PrepareCommand(cmd, conn, null, cmdType, cmdText, parameters); var val = cmd.ExecuteScalar(); cmd.Parameters.Clear(); return val; } } /// <summary> /// 为执行准备命令对象 /// </summary> /// <param name="cmd">command 对象</param> /// <param name="conn">连接对象</param> /// <param name="trans">事务对象</param> /// <param name="cmdType">命令类型</param> /// <param name="cmdText">命令字符串</param> /// <param name="cmdParms">参数集</param> private static void PrepareCommand(MySqlCommand cmd, MySqlConnection conn, MySqlTransaction trans, CommandType cmdType, string cmdText, IEnumerable<MySqlParameter> parameters) { if (conn.State != ConnectionState.Open) conn.Open(); cmd.Connection = conn; cmd.CommandText = cmdText; if (trans != null) cmd.Transaction = trans; cmd.CommandType = cmdType; if (parameters == null) return; foreach (var parm in parameters) cmd.Parameters.Add(parm); } } } |
View Details
(Yes it’s a long title, since people kept asking me to write about this and that too :) I do when it has a point.) While SQL databases are insanely useful tools, their monopoly in the last decades is coming to an end. And it’s just time: I can’t even count the things that were forced into relational databases, but never really fitted them. (That being said, relational databases will always be the best for the stuff that has relations.) But, the differences between NoSQL databases are much bigger […]
View Details语法: select * from table_name force index (index_name) where conditions; 使用 关键字 force
1 2 3 |
#########mysql强制使用指定索引查询 SELECT * FROM `yrd_pay_flow` FORCE INDEX(`idx_trxn_date`) WHERE trxn_date > '2017-08-12 59:59:59' AND trxn_date < '2016-06-23 00:00:00'; |
from:https://www.cnblogs.com/pc-boke/articles/9916986.html
View Details就一句话:
1 |
SELECT * from PrjOlc WHERE (Prj,SubID) in (SELECT Prj,SubID FROM SP where stage='设计' and 负责人 = 'XXX000') |
from:https://www.cnblogs.com/ShengunErshu/p/14239690.html
View Details下午跑程序,在插入mysql时突然报错: ”The table‘xxxx’is full“ 而之前一直没问题的。 上网查了一下,都说临时表的问题,需要设置”tmp_table_size“: tmp_table_size 如果内存内的临时表超过该值,MySQL自动将它转换为硬盘上的MyISAM表。如果你执行许多高级GROUP BY查询并且有大量内存,则可以增加tmp_table_size的值。 http://www.2cto.com/database/201106/92968.html 感觉与我们服务器情况不太相符:我们没用到临时表,而且tmp_table_size已经非常大了。 再查到: mysql出现"the table is full"的问题,一般有两个原因: 一 .You are using the MEMORY (HEAP) storage engine; in this case you need to increase the value of the max_heap_table_size system variable. See Section 5.1.3, “Server System Variables”. 于是就修改Mysql的配置文件/etc/my.cnf,在[mysqld]下添加/修改两行: tmp_table_size = 256M max_heap_table_size = 256M 系统默认是16M,修改完后重启mysql 二.硬盘空间满了,清理硬盘即可. http://linux.net527.cn/fuwuqiyingyong/Mysql_shujuku/2011/1003/44014.html 在服务器df了一下,果然硬盘空间不够了,已经使用了100%。 追查下来,发现是mysql的日志文件将硬盘撑爆了,有大量的mysql-bin.000XXX之类的日志文件。 如何处理?很简单: (1)清除这些日志文件 (2)如果不需要的话,可以关闭mysql的bin-log功能。 具体操作: 这是数据库的操作日志,例如UPDATE一个表,或者DELETE一些数据,即使该语句没有匹配的数据,这个命令也会存储到日志文件中,还包括每个语句执行的时间,也会记录进去的 这样做主要有以下两个目的: 1:数据恢复 如果你的数据库出问题了,而你之前有过备份,那么可以看日志文件,找出是哪个命令导致你的数据库出问题了,想办法挽回损失。 2:主从服务器之间同步数据 主服务器上所有的操作都在记录日志中,从服务器可以根据该日志来进行,以确保两个同步。 处理方法分两种情况: 1:只有一个mysql服务器,那么可以简单的注释掉这个选项就行了。 vi /etc/my.cnf把里面的log-bin这一行注释掉,重启mysql服务即可。 2:如果你的环境是主从服务器,那么就需要做以下操作了。 A:在每个从属服务器上,使用SHOW SLAVE STATUS来检查它正在读取哪个日志。 B:使用SHOW MASTER LOGS获得主服务器上的一系列日志。 C:在所有的从属服务器中判定最早的日志,这个是目标日志,如果所有的从属服务器是更新的,就是清单上的最后一个日志。 D:清理所有的日志,但是不包括目标日志,因为从服务器还要跟它同步。 清理日志方法为: PURGE MASTER LOGS […]
View Details一,对记录的操作 1.创建有json字段的表
1 2 |
-- 创建表 CREATE TABLE t_json(id INT PRIMARY KEY, sname VARCHAR(20) , info JSON); |
2.插入记录
1 2 3 4 5 6 |
-- 插入含有json数组的记录 INSERT INTO t_json(id,sname,info) VALUES( 1, 'name1', JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME())); -- 插入含有json对象的记录 INSERT INTO t_json(id,sname,info) VALUES( 2, 'name2', JSON_OBJECT("age", 20, "time", now())); INSERT INTO t_json(id,sname,info) VALUES( 3, 'name3', '{"age":20, "time":"2018-07-14 10:52:00"}'); |
3.查询记录
1 2 3 4 5 |
-- 查询记录 SELECT sname,JSON_EXTRACT(info,'$.age') FROM t_json; SELECT sname,info->'$.age' FROM t_json; -- 查询key SELECT id,json_keys(info) FROM t_json; |
4.修改记录
1 2 3 4 5 6 7 8 |
-- 增加键 UPDATE t_json SET info = json_set(info,'$.ip','192.168.1.1') WHERE id = 2; -- 变更值 UPDATE t_json SET info = json_set(info,'$.ip','192.168.1.2') WHERE id = 2; -- 删除键 UPDATE t_json SET info = json_remove(info,'$.ip') WHERE id = 2; |
二,创建json值函数 1.JSON_ARRAY 生成json数组
1 2 3 |
-- JSON_ARRAY(val1,val2,val3...) -- 生成一个包含指定元素的json数组。 SELECT JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME()); -- [1, "abc", null, true, "10:37:08.000000"] |
2.JSON_OBJECT 生成json对象
1 2 3 |
-- JSON_OBJECT(key1,val1,key2,val2...) -- 生成一个包含指定K-V对的json object。如果有key为NULL或参数个数为奇数,则抛错。 SELECT JSON_OBJECT('age', 20, 'time', now()); -- {"id": 87, "name": "carrot"} |
3.JSON_QUOTE 加"号
1 2 3 |
-- JSON_QUOTE(json_val) -- 将json_val用"号括起来。 SELECT JSON_QUOTE('[1,2,3]'); -- "[1,2,3]" |
三,搜索json值函数 1.JSON_CONTAINS 指定数据是否存在
1 2 3 4 |
set @j = '{"a": 1, "b": 2, "c": {"d": 4}}'; -- JSON_CONTAINS(json_doc, val[, path]) -- 查询json文档是否在指定path包含指定的数据,包含则返回1,否则返回0。如果有参数为NULL或path不存在,则返回NULL。 SELECT JSON_CONTAINS(@j, '4', '$.c.d'); -- 1 |
2.JSON_CONTAINS_PATH 指定路径是否存在
1 2 3 4 5 |
-- JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...) -- 查询是否存在指定路径,存在则返回1,否则返回0。如果有参数为NULL,则返回NULL。 -- one_or_all只能取值"one"或"all",one表示只要有一个存在即可;all表示所有的都存在才行。 SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e'); -- 1 SELECT JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.c.d'); -- 1 |
3.JSON_EXTRACT 查找所有指定数据
1 2 3 4 5 6 |
-- JSON_EXTRACT(json_doc, path[, path] ...) -- 从json文档里抽取数据。如果有参数有NULL或path不存在,则返回NULL。如果抽取出多个path,则返回的数据封闭在一个json array里。 set @j2 = '[10, 20, [30, 40]]'; SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]'); -- 20 SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]'); -- [20, 10] SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]'); -- [30, 40] |
4.JSON_KEYS 查找所有指定键值
1 2 3 4 5 |
-- JSON_KEYS(json_doc[, path]) -- 获取json文档在指定路径下的所有键值,返回一个json array。如果有参数为NULL或path不存在,则返回NULL。 SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}'); -- ["a", "b"] SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}', '$.b'); -- ["c"] SELECT id,json_keys(info) FROM t_json; |
5.JSON_SEARCH 查找所有指定值的位置
1 2 3 4 5 6 7 8 9 10 11 12 |
-- JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...]) -- 查询包含指定字符串的paths,并作为一个json array返回。如果有参数为NUL或path不存在,则返回NULL。 -- one_or_all:"one"表示查询到一个即返回;"all"表示查询所有。 -- search_str:要查询的字符串。 可以用LIKE里的'%'或‘_’匹配。 -- path:在指定path下查。 SET @j3 = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]'; SELECT JSON_SEARCH(@j3, 'one', 'abc'); -- "$[0]" SELECT JSON_SEARCH(@j3, 'all', 'abc'); -- ["$[0]", "$[2].x"] SELECT JSON_SEARCH(@j3, 'all', 'abc', NULL, '$[2]'); -- "$[2].x" SELECT JSON_SEARCH(@j3, 'all', '10'); -- "$[1][0].k" SELECT JSON_SEARCH(@j3, 'all', '%b%'); -- ["$[0]", "$[2].x", "$[3].y"] SELECT JSON_SEARCH(@j3, 'all', '%b%', NULL, '$[2]'); -- "$[2].x" |
四,修改json值函数 1.JSON_ARRAY_APPEND 指定位置追加数组元素
1 2 3 4 5 6 7 8 |
-- JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...) -- 在指定path的json array尾部追加val。如果指定path是一个json object,则将其封装成一个json array再追加。如果有参数为NULL,则返回NULL。 SET @j4 = '["a", ["b", "c"], "d"]'; -- SELECT JSON_ARRAY_APPEND(@j4, '$[1][0]', 3); -- ["a", [["b", 3], "c"], "d"] SET @j5 = '{"a": 1, "b": [2, 3], "c": 4}'; SELECT JSON_ARRAY_APPEND(@j5, '$.b', 'x'); -- {"a": 1, "b": [2, 3, "x"], "c": 4} SELECT JSON_ARRAY_APPEND(@j5, '$.c', 'y'); -- {"a": 1, "b": [2, 3], "c": [4, "y"]} SELECT JSON_ARRAY_APPEND(@j5, '$', 'z'); -- [{"a": 1, "b": [2, 3], "c": 4}, "z"] |
2.JSON_ARRAY_INSERT 指定位置插入数组元素
1 2 3 4 5 6 7 |
-- JSON_ARRAY_INSERT(json_doc, path, val[, path, val] ...) -- 在path指定的json array元素插入val,原位置及以右的元素顺次右移。如果path指定的数据非json array元素,则略过此val;如果指定的元素下标超过json array的长度,则插入尾部。 SET @j6 = '["a", {"b": [1, 2]}, [3, 4]]'; SELECT JSON_ARRAY_INSERT(@j6, '$[1]', 'x'); -- ["a", "x", {"b": [1, 2]}, [3, 4]] SELECT JSON_ARRAY_INSERT(@j6, '$[100]', 'x'); -- ["a", {"b": [1, 2]}, [3, 4], "x"] SELECT JSON_ARRAY_INSERT(@j6, '$[1].b[0]', 'x'); -- ["a", {"b": ["x", 1, 2]}, [3, 4]] SELECT JSON_ARRAY_INSERT(@j6, '$[0]', 'x', '$[3][1]', 'y'); -- ["x", "a", {"b": [1, 2]}, [3, "y", 4]] |
3.JSON_INSERT 指定位置插入
1 2 3 4 |
-- JSON_INSERT(json_doc, path, val[, path, val] ...) -- 在指定path下插入数据,如果path已存在,则忽略此val(不存在才插入)。 SET @j7 = '{ "a": 1, "b": [2, 3]}'; SELECT JSON_INSERT(@j7, '$.a', 10, '$.c', '[true, false]'); -- {"a": 1, "b": [2, 3], "c": "[true, false]"} |
4.JSON_REPLACE 指定位置替换
1 2 3 |
-- JSON_REPLACE(json_doc, path, val[, path, val] ...) -- 替换指定路径的数据,如果某个路径不存在则略过(存在才替换)。如果有参数为NULL,则返回NULL。 SELECT JSON_REPLACE(@j7, '$.a', 10, '$.c', '[true, false]'); -- {"a": 10, "b": [2, 3]} |
5.JSON_SET 指定位置设置
1 2 3 |
-- JSON_SET(json_doc, path, val[, path, val] ...) -- 设置指定路径的数据(不管是否存在)。如果有参数为NULL,则返回NULL。 SELECT JSON_SET(@j7, '$.a', 10, '$.c', '[true, false]'); -- {"a": 10, "b": [2, 3], "c": "[true, false]"} |
6.JSON_MERGE 合并
1 2 3 4 5 6 7 8 9 |
-- JSON_MERGE(json_doc, json_doc[, json_doc] ...) -- merge多个json文档。规则如下: -- 如果都是json array,则结果自动merge为一个json array; -- 如果都是json object,则结果自动merge为一个json object; -- 如果有多种类型,则将非json array的元素封装成json array再按照规则一进行mege。 SELECT JSON_MERGE('[1, 2]', '[true, false]'); -- [1, 2, true, false] SELECT JSON_MERGE('{"name": "x"}', '{"id": 47}'); -- {"id": 47, "name": "x"} SELECT JSON_MERGE('1', 'true'); -- [1, true] SELECT JSON_MERGE('[1, 2]', '{"id": 47}'); -- [1, 2, {"id": 47}] |
7.JSON_REMOVE 指定位置移除
1 2 3 4 |
-- JSON_REMOVE(json_doc, path[, path] ...) -- 移除指定路径的数据,如果某个路径不存在则略过此路径。如果有参数为NULL,则返回NULL。 SET @j8 = '["a", ["b", "c"], "d"]'; SELECT JSON_REMOVE(@j8, '$[1]'); -- ["a", "d"] |
8.JSON_UNQUOTE 去"号
1 2 3 |
-- JSON_UNQUOTE(val) -- 去掉val的引号。如果val为NULL,则返回NULL。 SELECT JSON_UNQUOTE("\"123\""); -- 123 |
五,返回json值属性的函数 1.JSON_DEPTH 深度
1 2 3 4 5 6 |
-- JSON_DEPTH(json_doc) -- 获取json文档的深度。如果参数为NULL,则返回NULL。 -- 空的json array、json object或标量的深度为1。 SELECT JSON_DEPTH('{}'), JSON_DEPTH('[]'), JSON_DEPTH('true'); -- 1 1 1 SELECT JSON_DEPTH('[10, 20]'), JSON_DEPTH('[[], {}]'); -- 2 2 SELECT JSON_DEPTH('[10, {"a": 20}]'); -- 3 |
2.JSON_LENGTH 长度
1 2 3 4 5 6 7 8 9 |
-- JSON_LENGTH(json_doc[, path]) -- 获取指定路径下的长度。如果参数为NULL,则返回NULL。 -- 长度的计算规则: -- 标量的长度为1; -- json array的长度为元素的个数; -- json object的长度为key的个数。 SELECT JSON_LENGTH('[1, 2, {"a": 3}]'); -- 3 SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}'); -- 2 SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}', '$.b'); -- 1 |
[…]
View Details