T-SQL OPENJSON $ AS JSON无法正常工作

时间:2017-07-18 01:37:08

标签: sql-server json tsql sql-server-2016

任何人都可以告诉我为什么第一个例子有效,但第二个例子不是吗?对他来说,他们看起来应该等同于同样的事情......

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 个答案:

答案 0 :(得分: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''$'的行为方式。

来自OPENJSON

  

如果要从JSON属性返回嵌套的JSON片段,则为   必须提供AS JSON标志。 如果没有此选项,则属性   无法找到,OPENJSON返回NULL值而不是   引用的JSON对象或数组,或者它返回运行时错误   严格模式。

所以用严格模式尝试第二:

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

最终会出错:

  

在指定的JSON路径上找不到属性。