【SqlServer系列】JSON数据
1 概述
本文将结合MSDN简要概述JSON数据。
2 具体内容
JSON 是一种流行的数据格式,用于在现代 Web 和移动应用程序中交换数据。 JSON 还可用于在 Microsoft Azure DocumentDB 等 NoSQL 数据库中存储非结构化数据。 许多 REST Web 服务以 JSON 文本格式返回结果,或接受采用 JSON 格式的数据。 例如,大多数 Azure 服务(如 Azure 搜索、Azure 存储和 Azure DocumentDb)都提供返回或使用 JSON 的 REST 终结点。 JSON 也是用于通过 AJAX 调用在网页与 Web 服务器之间交换数据的主要格式。
2.1 将 JSON 集合转换为行集
1 DECLARE @json NVARCHAR(MAX) 2 SET @json = 3 N'[ 4 { "id" : 2,"info": { "name": "John", "surname": "Smith" }, "age": 25 }, 5 { "id" : 5,"info": { "name": "Jane", "surname": "Smith" }, "dob": "2005-11-04T12:00:00" } 6 ]' 7 8 SELECT * 9 FROM OPENJSON(@json) 10 WITH (id int 'strict $.id', 11 firstName nvarchar(50) '$.info.name', lastName nvarchar(50) '$.info.surname', 12 age int, dateOfBirth datetime2 '$.dob')
2.2 将 SQL Server 数据转换为 JSON 或导出 JSON
通过将 FOR JSON 子句添加到 SELECT 语句中,可将 SQL Server 数据或 SQL 查询结果的格式设置为 JSON。 使用 FOR JSON 委托从客户端应用程序到 SQL Server 的 JSON 输出格式。 有关详细信息,请参阅 借助 FOR JSON 将查询结果的格式设置为 JSON (SQL Server)。
以下示例使用 PATH 模式和 FOR JSON 子句。
1 SELECT id, firstName AS "info.name", lastName AS "info.surname", age, dateOfBirth as dob 2 FROM People 3 FOR JSON PATH
“应用程序池:” FOR JSON 子句将 SQL 结果的格式设置为 JSON 文本,该格式可提供给识别 JSON 的任何应用。 PATH 选项在 SELECT 子句中使用以点分隔的别名,以嵌套查询结果中的对象。
2.3 合并关系数据和 JSON 数据
SQL Server 提供混合模型,用于通过标准 Transact-SQL 语言存储和处理关系数据与 JSON 数据。 可以将 JSON 文档的集合组织到表中,在它们之间建立关系,将表中存储的强类型标量列与 JSON 列中存储的灵活键/值对合并,以及使用完整 Transact SQL 查询一个或多个表中的标量值和 JSON 值。
JSON 文本通常存储在 varchar 或 nvarchar 列中,并编制了纯文本形式的索引。 任何支持文本的 SQL Server 功能或组件均支持 JSON,因此 JSON 和其他 SQL Server 功能之间的交互几乎没有任何约束。你可以将 JSON 存储在内存中或临时表中、对 JSON 文本应用行级别安全性谓词等。
如果在单纯的 JSON 工作负载中,你想要使用专用于处理 JSON 文档的自定义查询语言,可以考虑 Microsoft Azure DocumentDB。
以下用例说明如何在 SQL Server中使用内置的 JSON 支持。
2.4 从格式化为 JSON 的 SQL Server 表返回数据
如果你的 Web 服务从数据库层提取数据并以 JSON 格式返回数据,或者在接受已格式化为 JSON 的数据的 JavaScript 框架或库中返回数据,则可以直接在 SQL 查询中设置 JSON 输出的格式。 你可以使用 FOR JSON 将 JSON 格式设置委托给 SQL Server,而非编写代码或者包含一个库来转换表格查询结果对象,然后将对象序列化为 JSON 格式。
例如,你可能想要生成符合 OData 规范的 JSON 输出。 Web 服务需要采用以下格式的请求和响应。
-
请求:
/Northwind/Northwind.svc/Products(1)?$select=ProductID,ProductName
-
响应:
{"@odata.context":"http://services.odata.org/V4/Northwind/Northwind.svc/$metadata#Products(ProductID,ProductName)/$entity","ProductID":1,"ProductName":"Chai"}
此 OData URL 代表针对 ID 为 1 的产品的 ProductID 和 ProductName 列的请求。 可以使用 FOR JSON 按 SQL Server 中所需的格式设置输出格式。
1 SELECT 'http://services.odata.org/V4/Northwind/Northwind.svc/$metadata#Products(ProductID,ProductName)/$entity' 2 AS '@odata.context', 3 ProductID, Name as ProductName 4 FROM Production.Product 5 WHERE ProductID = 1 6 FOR JSON AUTO
此查询的输出是完全符合 OData 规范的 JSON 文本。 格式设置和转义由 SQL Server 处理。 SQL Server 还可将查询结果的格式设置为任何格式,如 OData JSON 或 GeoJSON - 有关详细信息,请参阅 Returning spatial data in GeoJSON format(以 GeoJSON 格式返回空间数据)。
2.5 使用 SQL 查询分析 JSON 数据
如果必须筛选或聚合 JSON 数据以用于报告,可以使用 OPENJSON 将 JSON 转换为关系格式。 然后,使用标准 Transact-SQL 和内置函数来准备报告。
1 SELECT Tab.Id, SalesOrderJsonData.Customer, SalesOrderJsonData.Date 2 FROM SalesOrderRecord AS Tab 3 CROSS APPLY 4 OPENJSON (Tab.json, N'$.Orders.OrdersArray') 5 WITH ( 6 Number varchar(200) N'$.Order.Number', 7 Date datetime N'$.Order.Date', 8 Customer varchar(200) N'$.AccountNumber', 9 Quantity int N'$.Item.Quantity' 10 ) 11 AS SalesOrderJsonData 12 WHERE JSON_VALUE(Tab.json, '$.Status') = N'Closed' 13 ORDER BY JSON_VALUE(Tab.json, '$.Group'), Tab.DateModified
可以在同一个查询中使用标准表列和来自 JSON 文本的值。 可以在 JSON_VALUE(Tab.json, '$.Status')
表达式上添加索引以提高查询的性能。 有关详细信息,请参阅 对 JSON 数据编制索引。
2.6 将 JSON 数据导入 SQL Server 表
如果必须将 JSON 数据从外部服务加载到 SQL Server,则可以使用 OPENJSON 将数据导入 SQL Server,而非分析应用程序层中的数据。
1 DECLARE @jsonVariable NVARCHAR(MAX) 2 3 SET @jsonVariable = N'[ 4 { 5 "Order": { 6 "Number":"SO43659", 7 "Date":"2011-05-31T00:00:00" 8 }, 9 "AccountNumber":"AW29825", 10 "Item": { 11 "Price":2024.9940, 12 "Quantity":1 13 } 14 }, 15 { 16 "Order": { 17 "Number":"SO43661", 18 "Date":"2011-06-01T00:00:00" 19 }, 20 "AccountNumber":"AW73565", 21 "Item": { 22 "Price":2024.9940, 23 "Quantity":3 24 } 25 } 26 ]' 27 28 INSERT INTO SalesReport 29 SELECT SalesOrderJsonData.* 30 FROM OPENJSON (@jsonVariable, N'$.Orders.OrdersArray') 31 WITH ( 32 Number varchar(200) N'$.Order.Number', 33 Date datetime N'$.Order.Date', 34 Customer varchar(200) N'$.AccountNumber', 35 Quantity int N'$.Item.Quantity' 36 ) 37 AS SalesOrderJsonData;
外部 REST 服务可以提供 JSON 变量的内容,这些内容将从客户端 JavaScript 框架作为参数发送,或者从外部文件加载。 你可以在 SQL Server 表中轻松插入、更新或合并来自 JSON 文本的结果。 有关此方案的详细信息,请参阅以下博客文章。
- Importing JSON data in SQL Server
- Upsert JSON documents in SQL Server 2016
- Loading GeoJSON data into SQL Server 2016。
2.7 将 JSON 文件加载到 SQL Server
文件中存储的信息可格式化为标准 JSON 或行分隔的 JSON。 SQL Server 可以导入 JSON 文件的内容,使用 OPENJSON 或 JSON_VALUE 函数分析内容,并将其加载到表中。
-
如果 JSON 文档存储在可由 SQL Server 访问的本地文件、共享网络驱动器或 Azure 文件存储位置,可以使用批量导入将 JSON 数据加载到 SQL Server。 有关此方案的详细信息,请参阅 Importing JSON files into SQL Server using OPENROWSET (BULK)(使用 OPENROWSET (BULK) 将 JSON 文件导入 SQL Server)。
-
如果行分隔的 JSON 文件存储在 Azure Blob 存储或 Hadoop 文件系统中,你可以使用 Polybase 来加载 JSON 文本,在 Transact-SQL 代码中分析文本,然后将其载入表中。
2.8 测试驱动内置的 JSON 支持
使用 AdventureWorks 示例数据库测试驱动内置 JSON 支持。 若要获取 AdventureWorks 示例数据库,必须从 此处。 将示例数据库还原到 SQL Server 2016 实例后,请解压缩示例文件,然后从 JSON 文件夹中打开“JSON Sample Queries procedures views and indexes.sql”文件。 运行此文件中的脚本,将某些现有数据的格式重新设置为 JSON 数据,对 JSON 数据运行示例查询和报告,为 JSON 数据编制索引,然后导入和导出 JSON。
下面是你可以对该文件中包含的脚本执行的操作。
-
使现有架构非规范化以创建 JSON 数据的列。
-
将 SalesReasons、SalesOrderDetails、SalesPerson、Customer 和包含销售订单相关信息的表中的信息存储到 SalesOrder_json 表的 JSON 列中。
-
将 EmailAddresses/PersonPhone 表中的信息作为 JSON 对象的数组存储到 Person_json 表中。
-
-
创建查询 JSON 数据的过程和视图。
-
为 JSON 数据编制索引 – 为 JSON 属性和全文索引创建索引。
-
导入和导出 JSON – 创建并运行以 JSON 结果形式导出 Person 和 SalesOrder 表内容,并使用 JSON 输入导入和更新 Person 与 SalesOrder 表的过程。
-
运行查询示例 – 运行一些查询,用于调用步骤 2 和 4 中创建的存储过程与视图。
-
清理脚本 – 如果你想要保留步骤 2 和 4 中创建的存储过程与视图,请不要运行此部件。
3 参考文献
【01】https://docs.microsoft.com/zh-cn/sql/relational-databases/json/json-data-sql-server
4 版权
- 感谢您的阅读,若有不足之处,欢迎指教,共同学习、共同进步。
- 博主网址:http://www.cnblogs.com/wangjiming/。
- 极少部分文章利用读书、参考、引用、抄袭、复制和粘贴等多种方式整合而成的,大部分为原创。
- 如您喜欢,麻烦推荐一下;如您有新想法,欢迎提出,邮箱:2016177728@qq.com。
- 可以转载该博客,但必须著名博客来源。