SQL Server 2017 OPENJSON解析时如何存储原始JSON对象到列
问题说明
需要在SQL Server中使用OPENJSON解析JSON数组时,将解析得到的每一个JSON对象以原始字符串形式存入结果集的OriginalObject列,避免后续将行数据重新转换为JSON产生的额外性能开销。
当前使用数据库版本:Microsoft SQL Server 2017 (RTM-CU21) (KB4557397) - 14.0.3335.7 (X64)
初始尝试的查询语句如下:
DECLARE @JSON NVARCHAR(MAX) = N'[ { "OrderNumber":"SO43659", "OrderDate":"2011-05-31T00:00:00", "AccountNumber":"AW29825", "ItemPrice":2024.9940, "ItemQuantity":1 }, { "OrderNumber":"SO43661", "OrderDate":"2011-06-01T00:00:00", "AccountNumber":"AW73565", "ItemPrice":2024.9940, "ItemQuantity":3 } ]' SELECT * FROM OPENJSON ( @JSON) WITH ( OrderNumber VARCHAR(200) , OrderDate VARCHAR(200) , AccountNumber NVARCHAR(MAX) , ItemPrice NVARCHAR(MAX) , ItemQuantity NVARCHAR(MAX) , OriginalObject NVARCHAR(MAX) AS JSON )
预期查询效果参考:
解决方案
给OriginalObject列指定JSON路径为'$'即可,$代表当前行对应的整个JSON对象上下文,搭配AS JSON关键字会直接返回该对象的原始JSON字符串,不需要额外做二次序列化,没有额外性能开销。
修正后的完整语句:
DECLARE @JSON NVARCHAR(MAX) = N'[ { "OrderNumber":"SO43659", "OrderDate":"2011-05-31T00:00:00", "AccountNumber":"AW29825", "ItemPrice":2024.9940, "ItemQuantity":1 }, { "OrderNumber":"SO43661", "OrderDate":"2011-06-01T00:00:00", "AccountNumber":"AW73565", "ItemPrice":2024.9940, "ItemQuantity":3 } ]' SELECT * FROM OPENJSON ( @JSON) WITH ( OrderNumber VARCHAR(200) , OrderDate DATETIME , AccountNumber VARCHAR(20) , ItemPrice DECIMAL(10,4) , ItemQuantity INT , OriginalObject NVARCHAR(MAX) '$' AS JSON )
补充说明:
- 原写法的问题是
OriginalObject列没有指定路径,默认会匹配JSON对象中名为OriginalObject的字段,自然无法拿到整个对象的内容 - 该写法兼容SQL Server 2016及以上所有正式版本,当前使用的2017 CU21版本完全支持
- 上述语句将其他字段的类型调整为更匹配业务数据的类型,可根据实际需求保留或修改
内容的提问来源于stack exchange,提问作者VivekL
相关产品推荐
相关产品推荐

