任何人都可以告诉我为什么第一个例子有效,但第二个例子不是吗?对他来说,他们看起来应该等同于同样的事情......
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,不正确。
我不确定为什么!
答案 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路径上找不到属性。