Json_value和Json_query找不到指定的路径

时间:2019-09-03 21:08:55

标签: sql json sql-server tsql

我正在尝试从以下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"}]}}

3 个答案:

答案 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_QUERYJSON字符串中提取对象或数组。如果该值不是对象或数组,则在NULL模式下结果为lax,在strict模式下结果为错误。
  • 函数JSON_VALUEJSON字符串中提取标量值。如果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是一个好主意。

正如您已经被告知的,我们可以使用其中之一:

  • JSON_VALUE()以从给定路径检索标量值。嵌套的JSON将作为字符串类型返回。
  • JSON_QUERY()提取JSON的一部分并将其作为JSON进行处理
  • 需要使用OpenJSON进入具有重复元素的JSON中,以便将片段作为派生集 row-by-row 返回。 WITH子句非常重要,它允许将OPENJSON的默认输出更改为列的 by-by-side (类似于PIVOT)。

在这种情况下,我们可以使用OPENJSON跳入第一级并返回在那里找到的对象。其中一些是标量值,可以作为类型化值返回,其他一些是JSON对象。在这种情况下,我们必须使用NVARCHAR(MAX)作为数据类型,并且必须分隔AS JSON才能继续返回值。

在您的JSON中,隔离专区是与1:n相关的集合。我们可以使用OPENJSON调用的级联,将第一个返回的片段用作输入,并使用另一个WITH子句提取隔室的列。

我希望,该示例能够给您足够的提示,您可以查询JSON的任何位置。祝你好运!