你可以在SQL JSON中混合字符串和对象输出吗?

时间:2017-12-15 13:43:45

标签: json sql-server json-query

我试图从我的SQL数据库构建一个JSON序列化的键/值对项列表(compat level 140)。诀窍是值可以是任何值:数字,字符串,null或其他JSON对象。

应该能够看起来像这样:

[{"key":"key1","value":"A String"},{"key":"key2","value":{"InnerKey":"InnerValue"}}]

然而,SQL似乎迫使我选择 字符串一个对象。

SELECT
       [key] = kvp.[key],
       [value] = CASE
              WHEN ISJSON(kvp.[value]) = 1 THEN JSON_QUERY(kvp.[value])
              ELSE '"' + kvp.[value] + '"'  -- See note below
              END
FROM (VALUES
        ('key1', 'This value is a string')
       ,('key2', '{"description":"This value is an object"}')
       ,('key3', '["This","value","is","an","array","of","strings"]')
       ,('key4', NULL)

       -- Without these lines, the above 4 work fine; with either of them, even those 4 are broken
       --,('key5', (SELECT [description] = 'This value is a dynamic object' FOR JSON PATH, WITHOUT_ARRAY_WRAPPER))
       --,('key6', JSON_QUERY((SELECT [description] = 'This value is a dynamic object' FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)))
) AS kvp([key], [value])
FOR JSON PATH

我是否尝试做一些SQL无法支持的事情,或者我只是缺少使其正常工作的正确语法?

*请注意,添加双引号似乎不应该是必要的。但没有这些,SQL无法包装字符串并生成错误的JSON:

[{"key":"key1","value":This value is a string},...

1 个答案:

答案 0 :(得分:2)

如果您的查询被修改为此,则可以:

SELECT
   [key] = kvp.[key],
   [value] = ISNULL(
          JSON_QUERY(CASE WHEN ISJSON(kvp.[value]) = 1 THEN kvp.[value] END),
          '"' + STRING_ESCAPE(kvp.[value], 'json') + '"'
   )
FROM (VALUES
   ('key1', 'This value is a "string"')
   ,('key2', '{"description":"This value is an object"}')
   ,('key3', '["This","value","is","an","array","of","strings"]')
   ,('key4', NULL)

   -- These now work
   ,('key5', (SELECT [description] = 'This value is a dynamic object' FOR JSON PATH, WITHOUT_ARRAY_WRAPPER))
   ,('key6', JSON_QUERY((SELECT [description] = 'This value is a dynamic object' FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)))
) AS kvp([key], [value])
FOR JSON PATH, INCLUDE_NULL_VALUES

当然,如果valueint,这还不够。另外,我无法解释为什么你的工作无效。