日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SQL Server 2016 JSON原生支持实例说明

發(fā)布時(shí)間:2023/12/20 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL Server 2016 JSON原生支持实例说明 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
原文:SQL Server 2016 JSON原生支持實(shí)例說明

背景

Microsoft SQL Server 對(duì)于數(shù)據(jù)平臺(tái)的開發(fā)者來說越來越友好。比如已經(jīng)原生支持XML很多年了,在這個(gè)趨勢(shì)下,如今也能在SQLServer2016中使用內(nèi)置的JSON。尤其對(duì)于一些大數(shù)據(jù)很數(shù)據(jù)接口的解析環(huán)節(jié)來說這顯得非常有價(jià)值。與我們現(xiàn)在所做比如在SQL中使用CLR或者自定義的函數(shù)來解析JSON相比較,新的內(nèi)置JSON會(huì)大大提高性能,同時(shí)優(yōu)化了編程以及增刪查改等方法。

??? 那么是否意味著我們可以丟棄XML,然后開始使用JSON?當(dāng)然不是,這取決于數(shù)據(jù)輸出處理的目的。如果有一個(gè)外部的通過XML與外部交互數(shù)據(jù)的服務(wù)并且內(nèi)外的架構(gòu)是一致的,那么應(yīng)該是使用XML數(shù)據(jù)類型以及原生的函數(shù)。如果是針對(duì)微型服務(wù)架構(gòu)或者動(dòng)態(tài)元數(shù)據(jù)和數(shù)據(jù)存儲(chǔ),那么久應(yīng)該利用最新的JSON函數(shù)。

實(shí)例

??? 當(dāng)使用查詢這些已經(jīng)有固定架構(gòu)的JSON的數(shù)據(jù)表時(shí),使用“FOR JSON” 提示在你的T-SQL腳本后面,用這種方式以便于格式化輸出。一下實(shí)例我使用了SQLServer 2016 Worldwide Importers sample database,可以在GitHub上直接下載下來(下載地址)。看一下視圖Website.customers。我們查詢一個(gè)數(shù)據(jù)并格式化輸出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=1FOR JSON AUTO

  

?

請(qǐng)注意我們有一個(gè)地理數(shù)據(jù)類型列(DeliveryLocation),這需要引入兩個(gè)重要的變通方案(標(biāo)黃):

首先,需要轉(zhuǎn)換一個(gè)string字符,否則就會(huì)報(bào)錯(cuò):

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

其次,JSON采用鍵值對(duì)的語法因此必須指定一個(gè)別名來轉(zhuǎn)換數(shù)據(jù),如果失敗會(huì)出現(xiàn)下面的錯(cuò)誤:

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.

確認(rèn)了這些,改寫的格式化輸出如下:

[{"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": ""} ]

  

?

當(dāng)然也可以使用JSON作為輸入型DML語句,例如INSERT/UPDATE/DELETE 語句中使用“OPENJSON”。因此可以在所有的數(shù)據(jù)操作上加入JSON提示。

如果不了解數(shù)據(jù)結(jié)構(gòu)或者想讓其更加靈活,那么可以將數(shù)據(jù)存儲(chǔ)為一個(gè)JSON格式的字符類型,改列的類型可以使NVARCHAR 類型。Application.People 表中的CustomFields 列就是典型這種情況??梢杂萌缦抡Z句看一下表格格式這個(gè)列的內(nèi)容:

declare @json nvarchar(max)SELECT @json=[CustomFields] FROM [WideWorldImporters].[Application].[People] where PersonID=8select * from openjson(@json)

  

?

結(jié)果集在表格結(jié)果中的顯示:

?

用另一種方式來查詢這條記錄,前提是需要知道在JSON數(shù)據(jù)結(jié)構(gòu)和關(guān)鍵的名字,使用JSON_VALUE 和JSON_QUERY 函數(shù):

SELECTJSON_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 CommissionRateFROM [WideWorldImporters].[Application].[People]where PersonID=8

  

?

在表格結(jié)果集中展示表格格式的結(jié)果:

?

這個(gè)地方最關(guān)心就是查詢條件和添加索引。設(shè)想一下我們打算去查詢所有2011年以后雇傭的人,你可以運(yùn)行下面的查詢語句:

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 返回一個(gè)單一的文本值(nvarchar(4000))。需要轉(zhuǎn)換返回值到一個(gè)時(shí)間字段中,然后分離年來篩選查詢條件。實(shí)際執(zhí)行計(jì)劃如下:

?

為了驗(yàn)證如何對(duì)JSON內(nèi)容創(chuàng)建索引,需要?jiǎng)?chuàng)建一個(gè)計(jì)算列。為了舉例說明,Application.People 表標(biāo)記版本,并且加入計(jì)算列,當(dāng)系統(tǒng)版本為ON的時(shí)候不支持。我們這里使用Sales.Invoices表,其中ReturnedDeliveryData 中插入json數(shù)據(jù)。接下來獲取數(shù)據(jù),感受一下:

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

  

?

發(fā)現(xiàn)結(jié)果集第一個(gè)event都是“Ready for collection”:

?

然后獲取2016年3月的發(fā)票數(shù)據(jù):

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'

  

實(shí)際執(zhí)行計(jì)劃如下:

?

??? 加入一個(gè)計(jì)算列叫做“ReadyDate”, 準(zhǔn)備好集合表達(dá)式的結(jié)果:

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

  

?

之后,重新執(zhí)行查詢,但是使用新的計(jì)算列作為條件:

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

  

?

執(zhí)行計(jì)劃是一樣的,除了SSMS建議的缺失索引:

?

因此,根據(jù)建議在計(jì)算列上建立索引來幫助查詢,建立索引如下:

/* 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

  

?

我們重新執(zhí)行查詢驗(yàn)證執(zhí)行計(jì)劃:

?

有了索引之后,大大提升了性能,并且查詢JSON的速度和表列是一樣快的。

總結(jié):

本篇通過對(duì)SQL2016 中的新增的內(nèi)置JSON進(jìn)行了簡(jiǎn)單介紹,主要有如下要點(diǎn):

?

  • JSON能在SQLServer2016中高效的使用,但是JSON并不是原生數(shù)據(jù)類型;
  • 如果使用JSON格式必須為輸出結(jié)果是表達(dá)式的提供別名;
  • JSON_VALUE 和 JSON_QUERY? 函數(shù)轉(zhuǎn)移和獲取Varchar格式的數(shù)據(jù),因此必須將數(shù)據(jù)轉(zhuǎn)譯成你需要的類型。
  • 在計(jì)算列的幫助下查詢JSON可以使用索引進(jìn)行優(yōu)化。

總結(jié)

以上是生活随笔為你收集整理的SQL Server 2016 JSON原生支持实例说明的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。