2017-07-18 37 views
2

有誰能告訴我爲什麼第一個例子有效,但第二個例子不行?對我來說,他們看起來應該等同於相同的東西...

DECLARE @prmInputData NVARCHAR(MAX) = '{ "a": { "b": 1, "c": 2 } }' 

SELECT b, c, a 
FROM OPENJSON(@prmInputData, '$') 
WITH (
    b INT '$.a.b', 
    c INT '$.a.c', 
    a NVARCHAR(MAX) '$.a' AS JSON 
) 

SELECT b, c, a 
FROM OPENJSON(@prmInputData, '$.a') 
WITH (
    b INT '$.b', 
    c INT '$.c', 
    a NVARCHAR(MAX) '$' AS JSON 
) 

第一個示例正確地返回「a」作爲JSON對象。

第二個示例不正確地返回「a」爲NULL。

我不知道爲什麼!

回答

1

現貨的差異簡單的方法是省略WITH部分

原始查詢:

DECLARE @prmInputData NVARCHAR(MAX) = '{ "a": { "b": 1, "c": 2 } }'; 

SELECT * 
FROM OPENJSON(@prmInputData, '$') 
WITH (
    b INT '$.a.b', 
    c INT '$.a.c', 
    a NVARCHAR(MAX) '$.a' AS JSON 
); 

SELECT * 
FROM OPENJSON(@prmInputData, '$.a') 
WITH (
    b INT '$.b', 
    c INT '$.c', 
    a NVARCHAR(MAX) '$' AS JSON 
); 

輸出:

╔═══╦═══╦════════════════════╗ 
║ b ║ c ║   a   ║ 
╠═══╬═══╬════════════════════╣ 
║ 1 ║ 2 ║ { "b": 1, "c": 2 } ║ 
╚═══╩═══╩════════════════════╝ 

vs 

╔═══╦═══╦══════╗ 
║ b ║ c ║ a ║ 
╠═══╬═══╬══════╣ 
║ 1 ║ 2 ║ NULL ║ 
╚═══╩═══╩══════╝ 

去除WITH後:

DECLARE @prmInputData NVARCHAR(MAX) = '{ "a": { "b": 1, "c": 2 } }'; 

SELECT * 
FROM OPENJSON(@prmInputData, '$'); 

SELECT * 
FROM OPENJSON(@prmInputData, '$.a'); 

結果:

╔═════╦════════════════════╦══════╗ 
║ key ║  value  ║ type ║ 
╠═════╬════════════════════╬══════╣ 
║ a ║ { "b": 1, "c": 2 } ║ 5 ║  -- 5 ObjectValue 
╚═════╩════════════════════╩══════╝ 

vs 

╔═════╦═══════╦══════╗ 
║ key ║ value ║ type ║ 
╠═════╬═══════╬══════╣ 
║ b ║  1 ║ 2 ║     -- 2 IntValue 
║ c ║  2 ║ 2 ║     -- 2 IntValue 
╚═════╩═══════╩══════╝ 

現在你可以檢查有路徑的行爲'$.a' VS '$'


OPENJSON

If you want to return a nested JSON fragment from a JSON property, you have to provide the AS JSON flag. Without this option, if the property can't be found, OPENJSON returns a NULL value instead of the referenced JSON object or array, or it returns a run-time error in strict mode .

那麼嚴格的方式試圖第二:

DECLARE @prmInputData NVARCHAR(MAX) = '{ "a": { "b": 1, "c": 2 } }'; 

SELECT * 
FROM OPENJSON(@prmInputData, '$.a') 
WITH (
    b INT '$.b', 
    c INT '$.c', 
    a NVARCHAR(MAX) 'strict $' AS JSON 
); 

這將結束與錯誤:

Property cannot be found on the specified JSON path.

+0

啊真有意思,謝謝。那麼有什麼辦法可以像我想在同一個OPENJSON查詢中一樣選擇多個圖層嗎? – NightCabbage