1. 程式人生 > >SQL Server 2016 JSON原生支援例項說明

SQL Server 2016 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)

結果集在表格結果中的顯示:

用另一種方式來查詢這條記錄,前提是需要知道在JSON資料結構和關鍵的名字,使用JSON_VALUEJSON_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

在表格結果集中展示表格格式的結果:

這個地方最關心就是查詢條件和新增索引。設想一下我們打算去查詢所有2011年以後僱傭的人,你可以執行下面的查詢語句:

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))。需要轉換返回值到一個時間欄位中,然後分離年來篩選查詢條件。實際執行計劃如下:

為了驗證如何對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”:

然後獲取2016年3月的發票資料:

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'

實際執行計劃如下:

    加入一個計算列叫做“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建議的缺失索引:

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

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

我們重新執行查詢驗證執行計劃:

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

總結:

本篇通過對SQL2016 中的新增的內建JSON進行了簡單介紹,主要有如下要點:

  • JSON能在SQLServer2016中高效的使用,但是JSON並不是原生資料型別;
  • 如果使用JSON格式必須為輸出結果是表示式的提供別名;
  • JSON_VALUE 和 JSON_QUERY  函式轉移和獲取Varchar格式的資料,因此必須將資料轉譯成你需要的型別。
  • 在計算列的幫助下查詢JSON可以使用索引進行優化。

相關推薦

SQL Server 2016 JSON原生支援例項說明

背景 Microsoft SQL Server 對於資料平臺的開發者來說越來越友好。比如已經原生支援XML很多年了,在這個趨勢下,如今也能在SQLServer2016中使用內建的JSON。尤其對於一些大資料很資料介面的解析環節來說這顯得非常有價值。與我們現在所做比如在SQL中使用CLR或者自定義的函式來解析

SQL ServerJSON支援

      SQL Server 2005開始支援XML資料型別,提供原生的XML資料型別、XML索引及各種管理或輸出XML格式的函式。隨著JSON的流行,SQL Server2016開始支援JSON資料型別,不僅可以直接輸出JSON格式的結果集,還能讀取JS

JSON in SQL Server 2016

sum finall exec log msdn eve har ctu type JSON functions in SQL Server enable you to analyze and query JSON data, transform JSON to relat

百度開發者中心資訊釋出:百度雲BCC/RDS正式支援Windows Server 2016SQL Server 2016

雲基因-百度造 百度雲是百度基於17年技術積累而為公有云需求者提供的具備穩定、高可用、可擴充套件的雲端計算服務,目前已推出了智慧大資料平臺——天算、智慧多媒體平臺——天像、智慧物聯網平臺——天工、以及人工智慧平臺——天智四大解決方案。 而在這些強大的平臺級解決方案背後,是由

SQL Server 2016 發送郵件功能

logs server img 註意 http 基本 3.5 net .net 3.5 --1 安裝好SQL Server 2016 --2 安裝.Net 3.5 由於SQL Server 2016 安裝不提示強制安裝.NET 3.5 但是還是需要安裝,數據庫發送郵件會使用

數據庫原理及應用(SQL Server 2016數據處理)【上海精品視頻課程】

應用 原理 sql 信息無處不在,數據處理無處不用。物質、信息、能源已經成為人類生存和發展的重要保障。數據庫的應用廣度深度及建設規模已經成為衡量一個國家信息化程度的一項重要標誌。數據庫技術是計算機學科的一個重要分支,反映了數據管理的最新技術。數據庫技術與計算機網絡、人工智能一起被稱為計算機三大

SQL Server 2016 共享功能目錄 不可修改

技術分享 麻煩 ima ·· log class 個人電腦 ... png x 個人電腦上沒有安裝MSSQL,以前需要鏈接數據庫寫SQL,都是在{VS ->>視圖->>SQL Server對象資源管理器}直接鏈接數據庫進行訪問操作的... 但是確實有

Saturday SQL Server 2016 初體驗

主界面 cbt 啟動界面 公眾號 微軟官網 .com 截圖 控制臺 euc 最近在開發一個有關數據庫的項目,我想用SQLite,但是SQLite的設計器不是特別友好,然後據說VS有一個集成的SQLite設計器,但是我用的VS2017親測並沒有,用戶體驗不佳,所以安裝一個SQ

SQL Server 2016新特性:Temporal Table

clu let tween 事務 之間 small 激活 設置 版本 什麽是系統版本的Temporal Table 系統版本的Temporal Table是可以保存歷史修改數據並且可以簡單的指定時間分析的用戶表。 這個Temporal Table就是系統版本的Tempora

SQL Server 2016授權說明-備望

sql server 2016授權說明SQL 2016授權方式有點復雜,說明如下:1、 版本:標準版本和企業版,軟件功能沒有差別,只是標準版有如下限制 :a) 內存最大識別64Gb) CPU最大識別4顆,且最多只能識別16個核心c) 集群只支持2臺主機而企業版則沒有上面的限

SQL Server 2016 Failover + ALwaysOn

所有者 檢測 禁用 ger sha 上進 定義 ecb cef 我們前面寫了很多關於SQL Server相關的文章,近期公司為了提高服務的可用性,就想到了部署AlwaysOn,之前的環境只是部署了SQL Server Failover Cluster,所以決定將雲端放一臺S

SQL Server 2016 Failover Cluster+ ALwaysOn--增多個偵聽器

always nag db4 ger img 51cto roc 今天 配置 我們前面3片文章介紹了SQL Server 2016 Failover Cluster+ ALwaysOn的完整配置,今天我們介紹一下如果給ALwaysOn增加多個客戶端訪問點,常規情況下,每個可

SQL Server 2016 Failover +AlwaysOn 增加數據庫到可用性組

服務器 water path eba dfa instance logback 個數 ilove SQL Server Failover +AlwaysOn 增加數據庫到可用性組前面幾篇文章都已經詳細介紹了SQL Server Failover +AlwaysOn 的配置,

SQL Server 2016新特性:DROP IF EXISTS

obj 宋體 fff article 特性 這一 ble family base 原文:SQL Server 2016新特性:DROP IF EXISTS ?? 在我們寫T-SQL要刪除某個對象(表、存儲過程等)時,一

FineReport9.0定義數據連接(創建與SQL Server 2016數據庫的連接)

數據連接 選擇 用戶 wid jdbc blog ros conf 驗證 1、下載並安裝好FineReport9.0和SQL Server 2016 2、開始——>所有應用——>Microsoft SQL Ser

安裝好SQL Server 2016,沒有自帶SSMS 工具

sqlhttps://docs.microsoft.com/zh-cn/sql/ssms/sql-server-management-studio-changelog-ssms?view=sql-server-2016#previous-ssms-releases 安裝:SQL Server Manageme

配置SQL Server 2016無域AlwaysOn(轉)

命令 火墻 地址 ons 五步 red 圖形 ssp 故障轉移群集 Windows Server 2016 以及 SQL Server 2016出來已有一段時間了,因為Windows Server 2016可以配置無域的Windows群集,因此也能夠以此來配置無域的SQL

SQL server 2016 安裝步驟

1.進入安裝中心:可以參考硬體和軟體要求、可以看到一些說明文件 2.選擇全新安裝模式繼續安裝 3.輸入產品祕鑰:這裡使用演示祕鑰進行 4.在協議中,點選同意,並點選下一步按鈕,繼續安裝 5.進入全域性規則檢查項,這裡可能要花費幾秒鐘,試具體情況而定

sql server 2016新特性 查詢儲存(Query Store)的效能影響

前段時間給客戶處理效能問題,遇到一個新問題, 客戶的架構用的是 alwayson ,並且硬體用的是4路96核心,記憶體1T ,全固態快閃記憶體盤,sql server 2016 。 問題  描述        客戶經常出現系統卡住的現象,從當時跟蹤的語句執行情況看  是補卡住了,但每次的阻塞源頭都不一樣,當

SQL Server 2016 Always Encrypted(始終加密)

Always Encrypted 功能旨在保護 Azure SQL Database 或 SQL Server 資料庫中儲存的敏感資料,如信用卡號或身份證號(例如美國社會安全號碼)。 始終加密允許客戶端對客戶端應用程式內的敏感資料進行加密,並且永遠不向 資料庫引擎 ( SQL