虽然现在win服务器已经几乎不用了,但是网上看到2016开始原生支持json 还是想试试
建立一个表 id int , json varchar(2000)
json字段中输入数据 {"root":"1","arr":["sdas","112","asd"]}
{"root":"2","arr":["sdas","112","asd"]}
{"root":"3","arr":["sdas","112","asd"]}
{"root":"1","arr":["sdas","112","asd"]}
{"root":"3","arr":["sdas","112","asd"]}
一共5行
简单介绍下几个函数
JSON_VALUE 返回的是 json某个字段的值 必须是 值 而不能是对象,对象无法返回,好比以上表中的数据 “arr“ 后面的 数组对象是无法返回的
JSON_VALUE 只能返回一个标量值。如果有一组嵌套对象要提取,必须使用 JSON_QUERY 函数。
再强调一遍,应注意 JSON_VALUE 返回的是 NVARCHAR。因此,除非添加 CAST,否则将会为文本编制索引。
那么我们运用条件查询,查询json串
简单的:
select * FROM t2 where json_value(json,'$.root') = '1';
运用 json_value 来 指定值 其中 $.root 是json的path
关于path网上截取一段
declare @v nvarchar(500) ='
{"name":"test",
"obj":{"arr":[1,"ofao",3,4,5],
}
}' select json_value(@v,'$.obj.arr[0]')
这里返回 1
和一般的数组对象一样 从 0 开始计数
返回数组对象的json
select json_query(json,'$.arr') FROM t2 where json_value(json,'$.root') = '1';
数组对象的取值可以用 json_value 套 json_query
来复杂一点的:
select json_value(json_query(json,'$.arr'),'$[0]') FROM t2 where json_value(json_query(json,'$.arr'),'$[1]') = '112';
增删改
JSON_MODIFY ( expression , path , newValue )
DECLARE @info NVARCHAR(100)='{"name":"John","skills":["C#","SQL"]}'
PRINT @info
-- Update name
SET @info=JSON_MODIFY(@info,'$.name','Mike')
PRINT @info
-- Insert surname
SET @info=JSON_MODIFY(@info,'$.surname','Smith')
PRINT @info
-- Delete name
SET @info=JSON_MODIFY(@info,'$.name',NULL)
PRINT @info
-- Add skill 这里可以为数组对象增加值或者创建新的数组对象
SET @info=JSON_MODIFY(@info,'append $.skills','Azure')
PRINT @info
接着上面创建的表来一句
UPDATE t2 set json = JSON_MODIFY(json,'$.root','5')
json字段中 root 的 值 都更新了
普通的table转换成json
测试一下基本的,从查询结果里面构造一个json 的格式
create table t1(ID int identity,name nvarchar(50),Chinese int ,Math int) insert into t1 values ('张三',90,80),('李四',75,90),('王五',68,100)
select * from t1 select * from t1 for json auto --查询结果
ID name Chinese Math
----------- -------------------------------------------------- ----------- -----------
1 张三 90 80
2 李四 75 90
3 王五 68 100 --json 格式
[{"ID":1,"name":"张三","Chinese":90,"Math":80},{"ID":2,"name":"李四","Chinese":75,"Math":90},{"ID":3,"name":"王五","Chinese":68,"Math":100}]
这个是默认模式下面使用json的查询结果。是不是十分清晰
然后我们再接再厉,第二波是这样纸的。假如我们要继续搞有层级关系的。我们还可以这样写。比方说把成绩放在一个叫points 的节点里面, 也是可以分层的
select ID,
name,
Chinese as [Points.Chinese],
Math as [Points.Math]
from t1 for json path --结果json
[
{"ID":1,"name":"张三","Points":{"Chinese":90,"Math":80}},
{"ID":2,"name":"李四","Points":{"Chinese":75,"Math":90}},
{"ID":3,"name":"王五","Points":{"Chinese":68,"Math":100}}
]
他们的分数就放在了json 里面的,被一个point 包住了。
如果说我要在这个结果里面添加一个头来包住,当然,我可以使用每个列来个别名 [root.col] 来实现,然而就有点啰嗦了。所以我们可以使用这个root 的关键字来添加一个顶节点
select ID,
name,
Chinese as [Points.Chinese],
Math as [Points.Math]
from t1 for json path,root('root') --返回的json结果
{"root":[
{"ID":1,"name":"张三","Points":{"Chinese":90,"Math":80}}, {"ID":2,"name":"李四","Points":{"Chinese":75,"Math":90}},{"ID":3,"name":"王五","Points":{"Chinese":68,"Math":100}}]}
当然咯,查询嘛,录入数据总是难免遇到null值,在这方面,for json 是如何处理的呢? 我在测试表添加一条数据在来查询
insert into t1 values ('赵六',100,null) select ID,
name,
Chinese as [Points.Chinese],
Math as [Points.Math]
from t1
where id in(3, 4)
for json auto --json的返回结果
[{"ID":3,"name":"王五","Points.Chinese":68,"Points.Math":100},{"ID":4,"name":"赵六","Points.Chinese":100}]
auto 模式下,如果是空值,将会忽略该属性。这样的话很容易就每一个集合返回的属性数量都不一来,这样不好看。所以应对这种情况,我们可以使用 incluede_null_values 关键字,即使是空值,也带出来
select ID,
name,
Chinese as [Points.Chinese],
Math as [Points.Math]
from t1
where id in(3, 4)
for json auto, include_null_values --json 的返回结果
[{"ID":3,"name":"王五","Points.Chinese":68,"Points.Math":100},{"ID":4,"name":"赵六","Points.Chinese":100,"Points.Math":null}]
使用了这个关键字,就可以把空值带出来,里面的值是Null 值