SQL Server 2016 JSON原生帮助实例证实

发布时间:2019-02-04  栏目:MyBatis  评论:0 Comments

背景

Microsoft SQL Server
对于数据平台的开发者来说更是友好。比如曾经原生扶助XML很多年了,在那些样子下,近日也能在SQLServer2016中应用内置的JSON。越发对于部分大数额很数据接口的剖析环节来说那显得非凡有价值。与我们现在所做诸如在SQL中行使CLR或者自定义的函数来解析JSON相相比较,新的放置JSON会大大进步质量,同时优化了编程以及增删查改等方法。

   
那么是不是意味我们可以屏弃XML,然后起先应用JSON?当然不是,那有赖于数量输出处理的目标。即使有一个外部的经过XML与表面交互数据的劳动并且内外的架构是如出一辙的,那么应该是采用XML数据类型以及原生的函数。假若是本着微型服务架构或者动态元数据和多少存储,那么久应该利用流行的JSON函数。

背景

Microsoft SQL Server
对于数据平台的开发者来说越发友好。比如曾经原生帮衬XML很多年了,在这么些样子下,近日也能在SQLServer2016中选择内置的JSON。尤其对于一些大数量很数据接口的分析环节来说那突显煞是有价值。与大家前天所做诸如在SQL中利用CLR或者自定义的函数来解析JSON相比较,新的停放JSON会大大进步品质,同时优化了编程以及增删查改等方式。

   
那么是还是不是意味着大家可以屏弃XML,然后开始使用JSON?当然不是,那有赖于数量输出处理的目标。如若有一个外部的通过XML与表面交互数据的劳动并且内外的架构是一律的,那么应该是使用XML数据类型以及原生的函数。若是是本着微型服务架构或者动态元数据和多少存储,那么久应该采用流行的JSON函数。

实例

    当使用查询这几个早已有定点架构的JSON的数目表时,使用“FOR
JSON

指示在您的T-SQL脚本后边,用那种艺术以便于格式化输出。一下实例我动用了SQLServer
2016 Worldwide Importers sample
database,可以在GitHub上直接下载下来(下载地址)。看一下视图Website.customers。咱俩询问一个数据并格式化输出JSON格式:

SELECT [CustomerID]
      ,[CustomerName]
      ,[CustomerCategoryName]
      ,[PrimaryContact]
      ,[AlternateContact]
      ,[PhoneNumber]
      ,[FaxNumber]
      ,[BuyingGroupName]
      ,[WebsiteURL]
      ,[DeliveryMethod]
      ,[CityName]

 ,DeliveryLocation.ToString() as DeliveryLocation
      ,[DeliveryRun]
      ,[RunPosition]
  FROM [WideWorldImporters].[Website].[Customers]
  WHERE CustomerID=1
  FOR JSON AUTO

  

 

请留心大家有一个地理数据类型列(DeliveryLocation),那亟需引入三个基本点的变型方案(标黄):

第一,须求更换一个string字符,否则就会报错:

FOR JSON cannot serialize CLR objects. Cast CLR types explicitly into one of the supported types in FOR JSON queries.

协助,JSON选择键值对的语法因此必须指定一个别名来更换数据,如若失败会并发上面的荒唐:

Column expressions and data sources without names or aliases cannot be formatted as JSON text using FOR JSON clause. Add alias to the unnamed column or table.

确认了这个,改写的格式化输出如下:

[
    {
        "CustomerID": 1,
        "CustomerName": "Tailspin Toys (Head Office)",
        "CustomerCategoryName": "Novelty Shop",
        "PrimaryContact": "Waldemar Fisar",
        "AlternateContact": "Laimonis Berzins",
        "PhoneNumber": "(308) 555-0100",
        "FaxNumber": "(308) 555-0101",
        "BuyingGroupName": "Tailspin Toys",
        "WebsiteURL": "http://www.tailspintoys.com",
        "DeliveryMethod": "Delivery Van",
        "CityName": "Lisco",
        "DeliveryLocation": "POINT (-102.6201979 41.4972022)",
        "DeliveryRun": "",
        "RunPosition": ""
    }
]

  

 

当然也得以运用JSON作为输入型DML语句,例如INSERT/UPDATE/DELETE
语句中行使“OPENJSON”。由此可以在具有的多寡操作上参预JSON提醒。

比方不通晓数据结构或者想让其越发灵活,那么可以将数据存储为一个JSON格式的字符类型,改列的档次可以使NVARCHAR
类型。Application.People 表中的CustomFields
列就是第超级那种境况。可以用如下语句看一下报表格式这么些列的始末:

declare @json nvarchar(max)

SELECT @json=[CustomFields]
FROM [WideWorldImporters].[Application].[People]
where PersonID=8

select * from openjson(@json)

  

 

结果集在表格结果中的展现:

图片 1

 

用另一种办法来询问那条记下,前提是内需明白在JSON数据结构和紧要性的名字,使用JSON_VALUE
JSON_QUERY
函数:

  SELECT
       JSON_QUERY([CustomFields],'$.OtherLanguages') as OtherLanguages,
       JSON_VALUE([CustomFields],'$.HireDate') as HireDate,
       JSON_VALUE([CustomFields],'$.Title') as Title,
       JSON_VALUE([CustomFields],'$.PrimarySalesTerritory') as PrimarySalesTerritory,
       JSON_VALUE([CustomFields],'$.CommissionRate') as CommissionRate
  FROM [WideWorldImporters].[Application].[People]
  where PersonID=8

  

 

在报表结果集中浮现表格格式的结果:

图片 2

 

其一地点最关心就是查询条件和添加索引。设想一下大家打算去询问所有二〇一一年未来雇佣的人,你可以运行上面的查询语句:

SELECT personID,fullName,JSON_VALUE(CustomFields,'$.HireDate') as hireDate
FROM [WideWorldImporters].[Application].[People]
where IsEmployee=1
and year(cast(JSON_VALUE(CustomFields,'$.HireDate') as date))>2011

  

 

切记JSON_VALUE
再次回到一个十足的文本值(nvarchar(4000))。须要更换重临值到一个时间字段中,然后分别年来筛选查询条件。实际施行布置如下:

图片 3

 

为了求证如何对JSON内容成立索引,需求创立一个总计列。为了举例表明,Application.People
表标记版本,并且插足总结列,当系统版本为ON的时候不辅助。大家那边运用Sales.Invoices表,其中ReturnedDeliveryData
中插入json数据。接下来获取数据,感受一下:

SELECT TOP 100 [InvoiceID]
      ,[CustomerID]
      ,JSON_QUERY([ReturnedDeliveryData],'$.Events')
  FROM [WideWorldImporters].[Sales].[Invoices]

  

 

察觉结果集第三个event都是“Ready for collection”:

图片 4

 

接下来拿走二零一六年5月的发票数额:

SELECT [InvoiceID]
      ,[CustomerID]
      ,CONVERT(datetime, CONVERT(varchar,JSON_VALUE([ReturnedDeliveryData],'$.Events[0].EventTime')),126)
  FROM [WideWorldImporters].[Sales].[Invoices]
  WHERE CONVERT(datetime, CONVERT(varchar,JSON_VALUE([ReturnedDeliveryData],'$.Events[0].EventTime')),126)
       BETWEEN '20160301' AND '20160331'

  

实质上执行安插如下:

图片 5

 

    参加一个计算列叫做“ReadyDate”, 准备好集合表明式的结果:

ALTER TABLE [WideWorldImporters].[Sales].[Invoices]
ADD ReadyDate AS CONVERT(datetime, CONVERT(varchar,JSON_VALUE([ReturnedDeliveryData],'$.Events[0].EventTime')),126)

  

 

事后,重新履行查询,然而利用新的计算列作为标准:

SELECT [InvoiceID]
      ,[CustomerID]
      ,ReadyDate
  FROM [WideWorldImporters].[Sales].[Invoices]
  WHERE ReadyDate BETWEEN '20160301' AND '20160331'

  

 

施行布署是如出一辙的,除了SSMS提议的缺失索引:

图片 6

 

所以,根据指出在测算列上建立索引来辅助查询,建立目录如下:

/*
The Query Processor estimates that implementing the following index could improve the query cost by 99.272%.
*/
CREATE NONCLUSTERED INDEX IX_Invoices_ReadyDate
ON [Sales].[Invoices] ([ReadyDate])
INCLUDE ([InvoiceID],[CustomerID])
GO

  

 

我们重新履行查询求证执行安插:

图片 7

 

有了目录之后,大大升级了品质,并且询问JSON的快慢和表列是如出一辙快的。

实例

    当使用查询这一个曾经有定点架构的JSON的数据表时,使用“FOR
JSON

提醒在您的T-SQL脚本前面,用这种艺术以便于格式化输出。一下实例我利用了SQLServer
2016 Worldwide Importers sample
database,可以在GitHub上直接下载下来(下载地址)。看一下视图Website.customers。大家查询一个数码并格式化输出JSON格式:

SELECT [CustomerID]
      ,[CustomerName]
      ,[CustomerCategoryName]
      ,[PrimaryContact]
      ,[AlternateContact]
      ,[PhoneNumber]
      ,[FaxNumber]
      ,[BuyingGroupName]
      ,[WebsiteURL]
      ,[DeliveryMethod]
      ,[CityName]

 ,DeliveryLocation.ToString() as DeliveryLocation
      ,[DeliveryRun]
      ,[RunPosition]
  FROM [WideWorldImporters].[Website].[Customers]
  WHERE CustomerID=1
  FOR JSON AUTO

  

 

请留心大家有一个地理数据类型列(DeliveryLocation),那需求引入八个首要的变更方案(标黄):

率先,须要更换一个string字符,否则就会报错:

FOR JSON cannot serialize CLR objects. Cast CLR types explicitly into one of the supported types in FOR JSON queries.

协助,JSON采纳键值对的语法由此必须指定一个别名来更换数据,即使失利会并发上边的荒唐:

Column expressions and data sources without names or aliases cannot be formatted as JSON text using FOR JSON clause. Add alias to the unnamed column or table.

肯定了这么些,改写的格式化输出如下:

[
    {
        "CustomerID": 1,
        "CustomerName": "Tailspin Toys (Head Office)",
        "CustomerCategoryName": "Novelty Shop",
        "PrimaryContact": "Waldemar Fisar",
        "AlternateContact": "Laimonis Berzins",
        "PhoneNumber": "(308) 555-0100",
        "FaxNumber": "(308) 555-0101",
        "BuyingGroupName": "Tailspin Toys",
        "WebsiteURL": "http://www.tailspintoys.com",
        "DeliveryMethod": "Delivery Van",
        "CityName": "Lisco",
        "DeliveryLocation": "POINT (-102.6201979 41.4972022)",
        "DeliveryRun": "",
        "RunPosition": ""
    }
]

  

 

当然也足以运用JSON作为输入型DML语句,例如INSERT/UPDATE/DELETE
语句中行使“OPENJSON”。因而得以在有着的多寡操作上出席JSON提醒。

假如不了解数据结构或者想让其进一步灵活,那么可以将数据存储为一个JSON格式的字符类型,改列的品类可以使NVARCHAR
类型。Application.People 表中的CustomFields
列就是独占鳌头那种情状。可以用如下语句看一下报表格式那一个列的情节:

declare @json nvarchar(max)

SELECT @json=[CustomFields]
FROM [WideWorldImporters].[Application].[People]
where PersonID=8

select * from openjson(@json)

  

 

结果集在表格结果中的展现:

图片 8

 

用另一种艺术来询问那条记下,前提是急需驾驭在JSON数据结构和关键的名字,使用JSON_VALUE
JSON_QUERY
函数:

  SELECT
       JSON_QUERY([CustomFields],'$.OtherLanguages') as OtherLanguages,
       JSON_VALUE([CustomFields],'$.HireDate') as HireDate,
       JSON_VALUE([CustomFields],'$.Title') as Title,
       JSON_VALUE([CustomFields],'$.PrimarySalesTerritory') as PrimarySalesTerritory,
       JSON_VALUE([CustomFields],'$.CommissionRate') as CommissionRate
  FROM [WideWorldImporters].[Application].[People]
  where PersonID=8

  

 

在表格结果集中突显表格格式的结果:

图片 9

 

以此地点最关怀就是查询条件和添加索引。设想一下大家打算去询问所有二〇一一年将来雇佣的人,你可以运作下边的查询语句:

SELECT personID,fullName,JSON_VALUE(CustomFields,'$.HireDate') as hireDate
FROM [WideWorldImporters].[Application].[People]
where IsEmployee=1
and year(cast(JSON_VALUE(CustomFields,'$.HireDate') as date))>2011

  

 

切记JSON_VALUE
再次来到一个单一的文本值(nvarchar(4000))。需求转移重返值到一个时间字段中,然后分别年来筛选查询条件。实际执行陈设如下:

图片 10

 

为了求证怎样对JSON内容创设索引,需求创制一个计算列。为了举例表达,Application.People
表标记版本,并且加入总结列,当系统版本为ON的时候不襄助。大家那里运用Sales.Invoices表,其中ReturnedDeliveryData
中插入json数据。接下来获取数据,感受一下:

SELECT TOP 100 [InvoiceID]
      ,[CustomerID]
      ,JSON_QUERY([ReturnedDeliveryData],'$.Events')
  FROM [WideWorldImporters].[Sales].[Invoices]

  

 

意识结果集第四个event都是“Ready for collection”:

图片 11

 

接下来拿走二〇一六年七月的发票数额:

SELECT [InvoiceID]
      ,[CustomerID]
      ,CONVERT(datetime, CONVERT(varchar,JSON_VALUE([ReturnedDeliveryData],'$.Events[0].EventTime')),126)
  FROM [WideWorldImporters].[Sales].[Invoices]
  WHERE CONVERT(datetime, CONVERT(varchar,JSON_VALUE([ReturnedDeliveryData],'$.Events[0].EventTime')),126)
       BETWEEN '20160301' AND '20160331'

  

其实履行陈设如下:

图片 12

 

    参加一个总计列叫做“ReadyDate”, 准备好集合表达式的结果:

ALTER TABLE [WideWorldImporters].[Sales].[Invoices]
ADD ReadyDate AS CONVERT(datetime, CONVERT(varchar,JSON_VALUE([ReturnedDeliveryData],'$.Events[0].EventTime')),126)

  

 

然后,重新履行查询,然则使用新的统计列作为条件:

SELECT [InvoiceID]
      ,[CustomerID]
      ,ReadyDate
  FROM [WideWorldImporters].[Sales].[Invoices]
  WHERE ReadyDate BETWEEN '20160301' AND '20160331'

  

 

实践布置是千篇一律的,除了SSMS提议的缺失索引:

图片 13

 

之所以,依据指出在计算列上建立索引来协助查询,建立目录如下:

/*
The Query Processor estimates that implementing the following index could improve the query cost by 99.272%.
*/
CREATE NONCLUSTERED INDEX IX_Invoices_ReadyDate
ON [Sales].[Invoices] ([ReadyDate])
INCLUDE ([InvoiceID],[CustomerID])
GO

  

 

咱俩再一次履行查询求证执行陈设:

图片 14

 

有了目录之后,大大提高了质量,并且询问JSON的快慢和表列是平等快的。

总结:

本篇通过对SQL2016 中的新增的放权JSON进行了简要介绍,紧要有如下要点:

 

  • JSON能在SQLServer2016中连忙的利用,不过JSON并不是原生数据类型;
  • 倘使接纳JSON格式必须为出口结果是表明式的提供别名;
  • JSON_VALUE 和 JSON_QUERY 
    函数转移和获取Varchar格式的数码,因此必须将数据转译成你要求的花色。
  • 在总计列的扶持下询问JSON能够行使索引举行优化。

总结:

本篇通过对SQL2016 中的新增的放到JSON举行了简便介绍,紧要有如下要点:

 

  • JSON能在SQLServer2016中火速的施用,可是JSON并不是原生数据类型;
  • 尽管运用JSON格式必须为出口结果是表明式的提供别名;
  • JSON_VALUE 和 JSON_QUERY 
    函数转移和得到Varchar格式的多寡,由此必须将数据转译成你必要的品种。
  • 在测算列的增援下询问JSON可以动用索引举行优化。

留下评论

网站地图xml地图