2017-07-18 1 views
2

Quelqu'un peut-il me dire pourquoi le premier exemple fonctionne, mais le second ne fonctionne pas? Pour moi, ils ressemblent, ils doivent correspondre à la même chose ...

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 
) 

Le premier exemple retourne « a » comme objet JSON, correctement.

Le deuxième exemple renvoie "a" comme NULL, de manière incorrecte.

Je ne sais pas pourquoi!

Répondre

1

moyen facile de repérer la différence est d'omettre WITH partie

Votre requête originale:

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 
); 

Sortie:

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

vs 

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

Après avoir enlevé WITH:

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

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

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

Résultat:

╔═════╦════════════════════╦══════╗ 
║ 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 
╚═════╩═══════╩══════╝ 

Maintenant, vous pouvez vérifier le chemin se comporte '$.a' vs '$'.


De 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 .

donc essayer seconde avec le mode strict:

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 
); 

Il finira avec l'erreur:

Property cannot be found on the specified JSON path.

+0

Ah qui est intéressant, je vous remercie . Alors est-il possible de sélectionner plusieurs couches comme je le veux dans la même requête OPENJSON? – NightCabbage