由于对mysql的函数并不了解,之前遇到了一个场景:

mysql表中有一个字段res_content 是一个由 longtext类型 (可以理解为一个更长的 varchar )保存的巨大的 JSON 对象,但是,由于录入的疏忽,导致这个json对象中的有一个属性值错误,需要重新修改这个json对象的属性值,于是,我将整个json对象,也就是res_content字段重新替换了一遍。=。= |||

一个json中小小的属性需要更新,却要替换整个json对象,仅仅因为它在数据库中是以一个字段存储的!!?这也太傻吊了!

这样做虽然简单粗暴,但很明显不符合我 追求完美 的性格,既然只有一个属性出错,那为什么不能直接替换这个JSON中具体的属性呢?而且这样的解决办法,如果处理上千万条JSON还可以减小mysql的性能开销,岂不美哉!?

当时并没有及时想到mysql函数,实际上mysql现在已经支持了大量的JSON字符串的操作函数,可以支持基本的需求。这也是我偶然间浏览 我的关注 里面的博文一个大神提供给我的思路:《 mysql替换某字段中的部分值 》,所以非常感谢这位博主。

不过,这个博主的文章只是替换已知字符串的值,比如 :http 改成 https,但对于json字符串,我们要想替换key所对应的value就涉及到两步:查询和替换,很明显,他这篇博客并不符合我的需求,不过确实给我提供了一个查阅mysql函数的思路。下面就来简单说说MySQL中用于替换JSON属性值的这个函数: JSON_REPLACE( json_doc , path , val [, path , val ] ...)

JSON_REPLACE():

官方的第一句解释是:Replaces existing values in a JSON document and returns the result。就冲这句话,基本可以锁定它就是我要找的解决方案。我们来看一下官方的示例:

mysql> SET @j = '{ "a": 1, "b": [2, 3]}';
mysql> SELECT JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]');
+-----------------------------------------------------+
| JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]') |
+-----------------------------------------------------+
| {"a": 10, "b": [2, 3]}                              |
+-----------------------------------------------------+

上面的例子很好理解, 首先,它定义了一个JSON字符串变量,然后通过JSON_REPLACE函数将这个变量中的属性a的值由1 改为了10,然后将属性c的值改为了‘[true, false]’,但由于json字符串中并没有属性 c 因此只有属性 a 修改成功了 。(这里需要注意,mysql函数仅仅是做数据转换,并不涉及到真正的增删改查,因此还需要配合具体的 UPDATE 才能够真正更新数据)

看过这个例子之后,我思考了一下我的应用场景,只需要在更新的sql语句中调用 JSON_REPLACE 函数,将json对象所对应的字段比作上面的JSON字符串变量,然后通过 ‘$xxx’ 匹配到我所希望修改的值,然后就可以成功修改JSON对象中的属性了。

现在我有一张 employee表 ,它的 last_name 字段是一个简单的JSON字符串:

现在,我希望修改 emp_id = 1 的记录,将这条记录中last_name中的 name 改成“ Harry ”, gender 改成 “ ”。于是我执行了下面的SQL:

UPDATE employee 
SET last_name = json_replace(last_name, '$.name', "Harry", "$.gender", "女") 
WHERE emp_id = 1;

这里注意,我特意将 "$.gender" 写为双引号,目的就是为了测试这样的通配是否可以生效,执行成功后,查询结果如下:

可以看到,last_name字段中的name属性已经修改成Harry,gender也被修改成了“女”,因此通配符 用双引、单引都是可以的。

除了JSON_REPLACE()函数,还有很多其他的json函数,如JSON_REMOVE()等,具体函数用法可以查看官方文档:

https://dev.mysql.com/doc/refman/5.7/en/json-functions.html

里面还贴心的将用法进行了归类:

但是,这些函数应该都对mysql数据库的版本比较敏感,一般对 MySQL5.7 以上的版本支持比较理想,个别函数可能需要5.7.8以上,我的数据库是5.7.23,因此JSON_REPLACE()用着还可以,如果你的版本在5.7以下,就得好好看看是否支持这些函数了。

简单查看MySQL数据库的版本:SELECT VERSION();

综上,就是关于如何修改JSON字符串中属性值的函数 JSON_REPLACE() 的简单介绍,欢迎文末留言。

JSON _SET( json _doc, path, val[, path, val] ...) JSON _INSERT( json _doc, path, val[, path, val] ...) JSO... JSON 是 JavaScript Object Notation(JavaScript 对象表示法)的缩写,是一个轻量级的,基于文本的,跨语言的数据交换格式。易于阅读和编写。数 :十进制数,不能前导0,可以为负数或小数,还可以为e或E表示的指数。字符串:字符串必须用双引号括起来。布尔 :true、false。数组:一个由零或多个 组成的有序序列。每个 可以为任意类型。数组使用方括号[ ]括起来,元素之间用逗号分隔。对象:一个由零或者多个键 对组成的无序集合。 MySQL 5.7.8中引入了 json 字段,这种类型的字段使用的频率比较低,但是在实际操作中,有些业务仍然在用,我们以此为例,介绍下 json 字段的操作方法: 还是从例子看起: mysql > create table test1(id int,info json ); Query OK, 0 rows affected (0.02 sec) mysql > insert into test1 values (1,'{name:yeyz,age:26}'),(2,'{name:zhangsan,age:30}'),(3,'{name:lisi,age:35}'); 需求描述:在看 mysql 中关于 json 的内容,通过 json _ replace 函数 可以实现对 json 的替换,在此记录下.操作过程:1.查看带有 json 数据类型的表 mysql > select * from tab_ json ;+----+---------------------------------------------------------------------------------... 11.10.9 JSON _ REPLACE ( json _doc,path,val[,path,val] ...) 函数 JSON _ REPLACE ( json _doc,path,val[,path,val] ...) 函数 用于更新 JSON 数据中指定Key的数据。使用示例如下: mysql > SELECT JSON _ REPLACE (content,'$.age',20) FROM test... JSON .stringify(value, replace r, space) value any JavaScript value, usually an object or array. replace r an optional parameter that determines how object values are stringified for objects. It can be a function or an array of strings. space an optional parameter that specifies the indentation of nested structures. If it is omitted, the text will be packed without extra whitespace. If it is a number, it will specify the number of spaces to indent at each level. If it is a string (such as '\t' or ' '), it contains the characters used to indent at each level. This method produces a JSON text from a JavaScript value. When an object value is found, if the object contains a to JSON method, its to JSON method will be called and the result will be stringified. A to JSON method does not serialize: it returns the value represented by the name/value pair that should be serialized, or undefined if nothing should be serialized. The to JSON method will be passed the key associated with the value, and this will be bound to the value For example, this would serialize Dates as ISO strings. Date.prototype.to JSON = function (key) { function f(n) { // Format integers to have at least two digits. return n < 10 ? '0' + n : n; return this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' + f(this.getUTCSeconds()) + 'Z'; You can provide an optional replace r method. It will be passed the key and value of each member, with this bound to the containing object. The value that is returned from your method will be serialized. If your method returns undefined, then the member will be excluded from the serialization. If the replace r parameter is an array of strings, then it will be used to select the members to be serialized. It filters the results such that only members with keys listed in the replace r array are stringified. Values that do not have JSON representations, such as undefined or functions, will not be serialized. Such values in objects will be dropped; in arrays they will be replace d with null. You can use a replace r function to replace those with JSON values. JSON .stringify(undefined) returns undefined. The optional space parameter produces a stringification of the value that is filled with line breaks and indentation to make it easier to read. If the space parameter is a non-empty string, then that string will be used for indentation. If the space parameter is a number, then the indentation will be that many spaces. Example: text = JSON .stringify(['e', {pluribus: 'unum'}]); // text is '["e",{"pluribus":"unum"}]' text = JSON .stringify(['e', {pluribus: 'unum'}], null, '\t'); // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' text = JSON .stringify([new Date()], function (key, value) { return this[key] instanceof Date ? 'Date(' + this[key] + ')' : value; // text is '["Date(---current time---)"]' JSON .parse(text, reviver) This method parses a JSON text to produce an object or array. It can throw a SyntaxError exception. The optional reviver parameter is a function that can filter and transform the results. It receives each of the keys and values, and its return value is used instead of the original value. If it returns what it received, then the structure is not modified. If it returns undefined then the member is deleted. Example: // Parse the text. Values that look like ISO date strings will // be converted to Date objects. myData = JSON .parse(text, function (key, value) { var a; if (typeof value === 'string') { /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); if (a) { return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6])); return value; myData = JSON .parse('["Date(09/09/2001)"]', function (key, value) { var d; if (typeof value === 'string' && value.slice(0, 5) === 'Date(' && value.slice(-1) === ')') { d = new Date(value.slice(5, -1)); if (d) { return d; return value; This is a reference implementation. You are free to copy, modify, or redistribute. MySQL json 查询之 json _insert、 json _merge_patch、 json _merge_preserve、josn_remove、 json _ replace json _set json _insert就是向 json 中插入,如果不存在则插入,存在则忽略 json _ replace 就是替换 json 中的项,如果不存在则忽略,存在则替换 json _set结合前面俩个,存在则替换,不存在则插入 json _merge_patch多个 json 进行合并,相同键名,后面的覆盖前面的,如果 是对象,则递归进行处 //这是直接用raplace直接替换的 当作字符串替换 update cxr_region_performance set district_manager= replace (district_manager, 'aa', 'bb') where JSON _OVERLAPS(district_manager -> '$[*].cxrEmployeeName', cast('[ ]' as json ));