我正在尝试从以下JSON解析数据。我知道JSON_VALUE和JSON_QUERY之间存在差异,但是我试图使路径结构正确。我正在使用STRICT选项来验证我的路径,到目前为止,对于JSON查询,除了string $之外,其他所有操作都因找不到路径而失败。一旦添加.data.taskData,路径似乎就炸毁了。任何帮助将不胜感激。
我将以下JSON设置为@json
declare @json nvarchar(max)
SELECT JSON_VALUE(@json, 'strict$.data.taskData.startedLocation') as json
select JSON_QUERY(@json, 'strict$.data.taskData.startedLocation') as json
下面是我要解析的JSON
{"data.taskData":{"startedAtUtc":"2019-08-28T20:21:29.025Z","startedLocation":{"lat":60.7348366,"lon":-124.9856841},"additionalData":[],"bols":[{"number":"1234","product":{"id":"COFFEE","description":"GROUND COFFE 5LB CAN","plannedQuantity":1352,"uom":"PCS","supplier":"WALMART ","accountOf":"","class":"UNKNOWN","loadedQuantity":6600,"netQuantity":9993},"net":"9993"}],"compartments":[{"id":"1","capacity":3400,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"1","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1000","bol":"1234"}],"loadedQuantity":1000,"productID":"COFFEE"},{"id":"2","capacity":2000,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"2","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2000","bol":"1234"}],"loadedQuantity":2000,"productID":"COFFEE"},{"id":"3","capacity":1100,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"3","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1100","bol":"1234"}],"loadedQuantity":1100,"productID":"COFFEE"},{"id":"4","capacity":2700,"commodity":null,"consignee":null,"plannedQuantity":0,"tankID":"4","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2500","bol":"1234"}],"loadedQuantity":2500,"productID":"COFFEE"}],"detention":{"minutes":null,"reasonCode":null,"notes":null},"initialCompartments":[{"id":"1","capacity":3400,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"1"},{"id":"2","capacity":2000,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"2"},{"id":"3","capacity":1100,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"3"},{"id":"4","capacity":2700,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"4"}],"loadingComplete":"yes","loadingCompleteTime":"2019-08-28T20:23:05.453Z","uom":{"key":"PCS","category":"volume","shortDisplay":"p","longDisplay":"Pieces","conversionFactors":{"gal":0.0625,"L":0.2365882365,"c":4.2267528377}},"variances":[],"completedAtUtc":"2019-08-28T20:23:06.703Z","completedLocation":{"lat":61.7348308,"lon":-124.9856879},"finalCompartments":[{"id":"1","capacity":3400,"productID":"COFFEE","loadedQuantity":1000,"consignee":"KSUAC","tankID":"1"},{"id":"2","capacity":2000,"productID":"COFFEE","loadedQuantity":2000,"consignee":"KSUAC","tankID":"2"},{"id":"3","capacity":1100,"productID":"COFFEE","loadedQuantity":1100,"consignee":"KSUAC","tankID":"3"},{"id":"4","capacity":2700,"productID":"COFFEE","loadedQuantity":2500,"consignee":null,"tankID":"4"}]}}
答案 0 :(得分:0)
这有效:
select JSON_QUERY(@json, 'strict$."data.taskData".startedLocation') as json
SELECT JSON_VALUE(@json, 'strict$."data.taskData".startedLocation.lat') as json
答案 1 :(得分:0)
您需要考虑以下因素:
JSON
对象或标量值,并且路径以美元符号$
开头或键中包含特殊字符,则需要用引号""
括起来JSON_QUERY
从JSON
字符串中提取对象或数组。如果该值不是对象或数组,则在NULL
模式下结果为lax
,在strict
模式下结果为错误。JSON_VALUE
从JSON
字符串中提取标量值。如果path
指向非标量值,则在NULL
模式下结果为lax
,在strict
模式下结果为错误JSON
字符串并以表的形式获取结果时,请使用OPENJSON
表值函数。使用示例数据,您可以尝试以下示例:
DECLARE @json nvarchar(max) = N'{"data.taskData":{"startedAtUtc":"2019-08-28T20:21:29.025Z","startedLocation":{"lat":60.7348366,"lon":-124.9856841},"additionalData":[],"bols":[{"number":"1234","product":{"id":"COFFEE","description":"GROUND COFFE 5LB CAN","plannedQuantity":1352,"uom":"PCS","supplier":"WALMART ","accountOf":"","class":"UNKNOWN","loadedQuantity":6600,"netQuantity":9993},"net":"9993"}],"compartments":[{"id":"1","capacity":3400,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"1","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1000","bol":"1234"}],"loadedQuantity":1000,"productID":"COFFEE"},{"id":"2","capacity":2000,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"2","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2000","bol":"1234"}],"loadedQuantity":2000,"productID":"COFFEE"},{"id":"3","capacity":1100,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"3","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1100","bol":"1234"}],"loadedQuantity":1100,"productID":"COFFEE"},{"id":"4","capacity":2700,"commodity":null,"consignee":null,"plannedQuantity":0,"tankID":"4","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2500","bol":"1234"}],"loadedQuantity":2500,"productID":"COFFEE"}],"detention":{"minutes":null,"reasonCode":null,"notes":null},"initialCompartments":[{"id":"1","capacity":3400,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"1"},{"id":"2","capacity":2000,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"2"},{"id":"3","capacity":1100,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"3"},{"id":"4","capacity":2700,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"4"}],"loadingComplete":"yes","loadingCompleteTime":"2019-08-28T20:23:05.453Z","uom":{"key":"PCS","category":"volume","shortDisplay":"p","longDisplay":"Pieces","conversionFactors":{"gal":0.0625,"L":0.2365882365,"c":4.2267528377}},"variances":[],"completedAtUtc":"2019-08-28T20:23:06.703Z","completedLocation":{"lat":61.7348308,"lon":-124.9856879},"finalCompartments":[{"id":"1","capacity":3400,"productID":"COFFEE","loadedQuantity":1000,"consignee":"KSUAC","tankID":"1"},{"id":"2","capacity":2000,"productID":"COFFEE","loadedQuantity":2000,"consignee":"KSUAC","tankID":"2"},{"id":"3","capacity":1100,"productID":"COFFEE","loadedQuantity":1100,"consignee":"KSUAC","tankID":"3"},{"id":"4","capacity":2700,"productID":"COFFEE","loadedQuantity":2500,"consignee":null,"tankID":"4"}]}}'
SELECT
JSON_QUERY(@json, 'strict $."data.taskData".startedLocation') AS StartedLocation,
JSON_VALUE(@json, 'strict $."data.taskData".startedLocation.lat') as Lat,
JSON_VALUE(@json, 'strict $."data.taskData".startedLocation.lon') as Lon
SELECT *
FROM OPENJSON(@json, 'strict $."data.taskData".compartments') AS Compartments
输出:
----------------------------------------------------------------
StartedLocation Lat Lon
----------------------------------------------------------------
{"lat":60.7348366,"lon":-124.9856841} 60.7348366 -124.9856841
----------------
key value type
----------------
0 {"id":"1","capacity":3400,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"1","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1000","bol":"1234"}],"loadedQuantity":1000,"productID":"COFFEE"} 5
1 {"id":"2","capacity":2000,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"2","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2000","bol":"1234"}],"loadedQuantity":2000,"productID":"COFFEE"} 5
2 {"id":"3","capacity":1100,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"3","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1100","bol":"1234"}],"loadedQuantity":1100,"productID":"COFFEE"} 5
3 {"id":"4","capacity":2700,"commodity":null,"consignee":null,"plannedQuantity":0,"tankID":"4","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2500","bol":"1234"}],"loadedQuantity":2500,"productID":"COFFEE"} 5
答案 2 :(得分:0)
尝试一下。在代码之后,我将对特色进行评论:
DECLARE @json NVARCHAR(MAX)=N'{
"data.taskData": {
"startedAtUtc": "2019-08-28T20:21:29.025Z",
"startedLocation": {
"lat": 60.7348366,
"lon": -124.9856841
},
"additionalData": [],
"bols": [
{
"number": "1234",
"product": {
"id": "COFFEE",
"description": "GROUND COFFE 5LB CAN",
"plannedQuantity": 1352,
"uom": "PCS",
"supplier": "WALMART ",
"accountOf": "",
"class": "UNKNOWN",
"loadedQuantity": 6600,
"netQuantity": 9993
},
"net": "9993"
}
],
"compartments": [
{
"id": "1",
"capacity": 3400,
"commodity": null,
"consignee": "KSUAC",
"plannedQuantity": 0,
"tankID": "1",
"additionalData": [],
"allLoadsValid": true,
"complete": true,
"error": false,
"locked": false,
"loads": [
{
"isFirst": true,
"quantity": "1000",
"bol": "1234"
}
],
"loadedQuantity": 1000,
"productID": "COFFEE"
},
{
"id": "2",
"capacity": 2000,
"commodity": null,
"consignee": "KSUAC",
"plannedQuantity": 0,
"tankID": "2",
"additionalData": [],
"allLoadsValid": true,
"complete": true,
"error": false,
"locked": false,
"loads": [
{
"isFirst": true,
"quantity": "2000",
"bol": "1234"
}
],
"loadedQuantity": 2000,
"productID": "COFFEE"
},
{
"id": "3",
"capacity": 1100,
"commodity": null,
"consignee": "KSUAC",
"plannedQuantity": 0,
"tankID": "3",
"additionalData": [],
"allLoadsValid": true,
"complete": true,
"error": false,
"locked": false,
"loads": [
{
"isFirst": true,
"quantity": "1100",
"bol": "1234"
}
],
"loadedQuantity": 1100,
"productID": "COFFEE"
},
{
"id": "4",
"capacity": 2700,
"commodity": null,
"consignee": null,
"plannedQuantity": 0,
"tankID": "4",
"additionalData": [],
"allLoadsValid": true,
"complete": true,
"error": false,
"locked": false,
"loads": [
{
"isFirst": true,
"quantity": "2500",
"bol": "1234"
}
],
"loadedQuantity": 2500,
"productID": "COFFEE"
}
],
"detention": {
"minutes": null,
"reasonCode": null,
"notes": null
},
"initialCompartments": [
{
"id": "1",
"capacity": 3400,
"commodity": null,
"consignee": null,
"plannedQuantity": null,
"tankID": "1"
},
{
"id": "2",
"capacity": 2000,
"commodity": null,
"consignee": null,
"plannedQuantity": null,
"tankID": "2"
},
{
"id": "3",
"capacity": 1100,
"commodity": null,
"consignee": null,
"plannedQuantity": null,
"tankID": "3"
},
{
"id": "4",
"capacity": 2700,
"commodity": null,
"consignee": null,
"plannedQuantity": null,
"tankID": "4"
}
],
"loadingComplete": "yes",
"loadingCompleteTime": "2019-08-28T20:23:05.453Z",
"uom": {
"key": "PCS",
"category": "volume",
"shortDisplay": "p",
"longDisplay": "Pieces",
"conversionFactors": {
"gal": 0.0625,
"L": 0.2365882365,
"c": 4.2267528377
}
},
"variances": [],
"completedAtUtc": "2019-08-28T20:23:06.703Z",
"completedLocation": {
"lat": 61.7348308,
"lon": -124.9856879
},
"finalCompartments": [
{
"id": "1",
"capacity": 3400,
"productID": "COFFEE",
"loadedQuantity": 1000,
"consignee": "KSUAC",
"tankID": "1"
},
{
"id": "2",
"capacity": 2000,
"productID": "COFFEE",
"loadedQuantity": 2000,
"consignee": "KSUAC",
"tankID": "2"
},
{
"id": "3",
"capacity": 1100,
"productID": "COFFEE",
"loadedQuantity": 1100,
"consignee": "KSUAC",
"tankID": "3"
},
{
"id": "4",
"capacity": 2700,
"productID": "COFFEE",
"loadedQuantity": 2500,
"consignee": null,
"tankID": "4"
}
]
}
}';
-查询
SELECT FirstLevel.StartedAtUtc
,JSON_VALUE(FirstLevel.startedLocation,'$.lat') AS startedLocation_Lat
,JSON_VALUE(FirstLevel.startedLocation,'$.lon') AS startedLocation_Lon
,FirstLevel.additionalData
,FirstLevel.bols
,Sub_Compartments.id
,Sub_Compartments.capacity
,FirstLevel.loadingComplete
FROM OPENJSON(@json,'$."data.taskData"')
WITH(startedAtUtc DATETIME2
,startedLocation NVARCHAR(MAX) AS JSON
,additionalData NVARCHAR(MAX) AS JSON
,bols NVARCHAR(MAX) AS JSON
--compartments seems to be a 1:n related node
,compartments NVARCHAR(MAX) AS JSON
,loadingComplete NVARCHAR(10)
--and more
) FirstLevel
OUTER APPLY OPENJSON(FirstLevel.compartments)
WITH (id INT
,capacity INT
--more columns
) Sub_Compartments;
简而言之:
您的JSON是带有各种数据的完全嵌套的深层嵌套结构。返回全部将导致一个非常多余的平面表。用尽可能小的问题来查询此JSON是一个好主意。
正如您已经被告知的,我们可以使用其中之一:
在这种情况下,我们可以使用OPENJSON跳入第一级并返回在那里找到的对象。其中一些是标量值,可以作为类型化值返回,其他一些是JSON对象。在这种情况下,我们必须使用NVARCHAR(MAX)
作为数据类型,并且必须分隔AS JSON才能继续返回值。
在您的JSON中,隔离专区是与1:n相关的集合。我们可以使用OPENJSON调用的级联,将第一个返回的片段用作输入,并使用另一个WITH子句提取隔室的列。
我希望,该示例能够给您足够的提示,您可以查询JSON的任何位置。祝你好运!